使用C#中的命名空间在xml文档中查找特定节点

时间:2015-04-08 05:44:00

标签: c# xml xml-namespaces

我在Stackoverflow尝试了很多答案来解决我的问题,例如this one。但似乎没有一个可以在我的XML文档上工作。

这是我的XML

<w:wordDocument xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core"
  w:macrosPresent="no"
  w:embeddedObjPresent="no"
  w:ocxPresent="no"
  xml:space="preserve">
  <w:ignoreSubtree
    w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2" />
  ...
  <w:body>
    <w:p
      wsp:rsidR="009D1011"
      wsp:rsidRDefault="001D7CCD">
      ...

我正在尝试查找具有命名空间的<w:p>节点。

这是我最近的尝试:

string xmlNamespace = String.Empty;
XmlNamespaceManager nsmgr;
//xml is my XMLDocument
XmlNodeList nodeInfo = xml.GetElementsByTagName("w:wordDocument");
XmlAttributeCollection att = nodeInfo[0].Attributes;
xmlNamespace = Convert.ToString(nodeInfo[0].Attributes["xmlns"].Value);
nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("w", xmlNamespace);
XmlNode myNode = xml.DocumentElement.SelectSingleNode("w:wordDocument/w:body", nsmgr);

myNode始终返回 null

谁能告诉我我做错了什么?

1 个答案:

答案 0 :(得分:5)

您的代码问题:

  • 要获取用于给定前缀的命名空间(在这种情况下为w),您应该检查正确的xmlns:w属性(不是默认xmlns,也不要检查xmlns:alm之类的随机属性}或者在大多数情况下只是明确指定 - 例如,在有效的WordML文档中它永远不会改变。
  • 选择从根目录开始的元素,您需要从根(/w:....)使用XPath搜索,或者在具有根元素作为子元素的节点上执行select(文档本身)。

工作代码的可能变体:

xmlNamespace = Convert.ToString(nodeInfo[0].Attributes["xmlns:w"].Value);
nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("w", xmlNamespace);
XmlNode myNode = xml.SelectSingleNode("w:wordDocument/w:body", nsmgr);

nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("w", "http://schemas.microsoft.com/office/word/2003/wordml");
XmlNode myNode = xml.DocumentElement
    .SelectSingleNode("/w:wordDocument/w:body", nsmgr);

或者使用local-name()函数忽略名称空间:

XmlNode myNode = xml.SelectSingleNode(
    "/*[local-name()='wordDocument']/*[local-name()='body']", nsmgr);