// FIXME - can only get mapping if you know the prefix?! static string GetPrefixMappings(Office.CustomXMLPrefixMappings prefixMappings) { string s = ""; for (int i = 0; i < prefixMappings.Count; i++) { Office.CustomXMLPrefixMapping pm = prefixMappings[i]; s += "xmlns:" + pm.Prefix + "='" + pm.NamespaceURI + "' "; } return(s); }
/// <summary> /// Get an XPath for an XML node in the local XML tree. /// </summary> /// <param name="mnsmgr">A CustomXMLPrefixMappings containing the namespace mappings in the corresponding CustomXMLPart.</param> /// <param name="xn">The XmlNode to convert.</param> /// <param name="removeTextNode">True to get the XPath for the parent XML node, False otherwise.</param> /// <param name="xnsmgr">The XmlNamespaceManager for the local XML tree.</param> /// <returns>The corresponding XPath.</returns> internal static string XpathFromXn(Office.CustomXMLPrefixMappings mnsmgr, XmlNode xn, bool removeTextNode, XmlNamespaceManager xnsmgr) { string strThis = null; string strThisName = null; string ns = ""; XmlNode xnParent = xn.ParentNode; bool fCheckParent = true; switch (xn.NodeType) { case XmlNodeType.Element: strThisName = xn.LocalName; if (!String.IsNullOrEmpty(xn.NamespaceURI) && xnsmgr != null && mnsmgr != null && !string.IsNullOrEmpty(mnsmgr.LookupPrefix(xn.NamespaceURI))) { xnsmgr.AddNamespace(mnsmgr.LookupPrefix(xn.NamespaceURI), xn.NamespaceURI); ns = mnsmgr.LookupPrefix(xn.NamespaceURI) + ":"; } strThis = "/" + ns + strThisName + XpathPosFromXn(xn); break; case XmlNodeType.Attribute: strThisName = xn.LocalName; if (!String.IsNullOrEmpty(xn.NamespaceURI) && xnsmgr != null && mnsmgr != null) { xnsmgr.AddNamespace(mnsmgr.LookupPrefix(xn.NamespaceURI), xn.NamespaceURI); ns = mnsmgr.LookupPrefix(xn.NamespaceURI) + ":"; } strThis = "/@" + ns + strThisName; xnParent = xn.SelectSingleNode("..", null); break; case XmlNodeType.ProcessingInstruction: { strThis = "/processing-instruction("; strThis = strThis + ")" + XpathPosFromXn(xn); break; } case XmlNodeType.Text: //if the parent is an attribute (for this text node), we need to get it's parent's xpath instead if (xn.ParentNode.NodeType != XmlNodeType.Attribute && !removeTextNode) { strThis = "/text()" + XpathPosFromXn(xn); } else { strThis = ""; } break; case XmlNodeType.Comment: strThis = "/comment()" + XpathPosFromXn(xn); break; case XmlNodeType.Document: strThis = ""; fCheckParent = false; break; case XmlNodeType.EntityReference: case XmlNodeType.CDATA: strThis = "/text()" + XpathPosFromXn(xn); break; case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: break; } return(strThis.Insert(0, fCheckParent ? XpathFromXn(mnsmgr, xnParent, false, xnsmgr) : "")); }
/// <summary> /// Get an XPath for a CustomXMLNode. /// </summary> /// <param name="xn">The CustomXMLNode to convert.</param> /// <param name="xnsmgr">The XmlNamespaceManager for the local XML tree.</param> /// <param name="mxnNew">A new CustomXMLNode that's not in the local tree, and therefore should be ignored when trying to find the XPath.</param> /// <returns>The corresponding XPath.</returns> private static string XpathFromMxn(Office.CustomXMLNode xn, XmlNamespaceManager xnsmgr, Office.CustomXMLNode mxnNew) { try { Debug.Assert(xn != null, "cannot create an xpath from a null node"); string strThis = null; string strThisName = null; string ns = ""; bool fCheckParent = true; Office.CustomXMLNode xnParent = xn.ParentNode; Office.CustomXMLPrefixMappings mnsmgr = xn.OwnerPart.NamespaceManager; switch (xn.NodeType) { case Office.MsoCustomXMLNodeType.msoCustomXMLNodeElement: strThisName = xn.BaseName; if (!string.IsNullOrEmpty(xn.NamespaceURI)) { ns = mnsmgr.LookupPrefix(xn.NamespaceURI) + ":"; xnsmgr.AddNamespace(mnsmgr.LookupPrefix(xn.NamespaceURI), xn.NamespaceURI); } strThis = "/" + ns + strThisName + XpathPosFromMxn(xn, mxnNew); break; case Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute: strThisName = xn.BaseName; if (!string.IsNullOrEmpty(xn.NamespaceURI)) { ns = mnsmgr.LookupPrefix(xn.NamespaceURI) + ":"; xnsmgr.AddNamespace(mnsmgr.LookupPrefix(xn.NamespaceURI), xn.NamespaceURI); } strThis = "/@" + ns + strThisName; xnParent = xn.SelectSingleNode(".."); break; case Office.MsoCustomXMLNodeType.msoCustomXMLNodeProcessingInstruction: { strThis = "/processing-instruction("; strThis = strThis + ")" + XpathPosFromMxn(xn, mxnNew); break; } case Office.MsoCustomXMLNodeType.msoCustomXMLNodeText: strThis = "/text()" + XpathPosFromMxn(xn, mxnNew); break; case Office.MsoCustomXMLNodeType.msoCustomXMLNodeComment: strThis = "/comment()" + XpathPosFromMxn(xn, mxnNew); break; case Office.MsoCustomXMLNodeType.msoCustomXMLNodeDocument: strThis = ""; fCheckParent = false; break; case Office.MsoCustomXMLNodeType.msoCustomXMLNodeCData: strThis = "/text()" + XpathPosFromMxn(xn, mxnNew); break; } return(strThis.Insert(0, fCheckParent ? XpathFromMxn(xnParent, xnsmgr, mxnNew) : "")); } catch (COMException ex) { Debug.Fail(ex.Source, ex.Message); } return(string.Empty); }