XmlDocument.SelectSingleNode和xmlNamespace问题

Shl*_*emi 44 c# xml xmldocument selectnodes selectsinglenode

我正在将字符串加载到包含以下结构的XML文档:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">                  
  <ItemGroup>
    <Compile Include="clsWorker.cs" />        
  </ItemGroup>      
</Project>
Run Code Online (Sandbox Code Playgroud)

然后我将所有加载到xmldocument:

XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(Xml);
Run Code Online (Sandbox Code Playgroud)

然后出现以下问题:

XmlNode Node = xmldoc.SelectSingleNode("//Compile"); // return null
Run Code Online (Sandbox Code Playgroud)

当我从根元素(Project)中删除xmlns属性时,它的工作正常,如何改进我的SelectSingleNode以返回相关元素?

Fré*_*idi 83

您应该在调用SelectSingleNode()时使用XmlNamespaceManager:

XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlNode node = xmldoc.SelectSingleNode("//msbld:Compile", ns);
Run Code Online (Sandbox Code Playgroud)

  • 当我们确定源 xml 是一致和同质的时,如何省略所有命名空间的废话,这使简单的事情变得复杂? (3认同)
  • @Alex,这是随意的,我可以使用任何东西.重要的是在调用`AddNamespace()`和名称空间前缀时使用相同的名称. (2认同)
  • @Alex Jolig,假设您的模式都在标题中指定,您可以执行以下操作来动态添加它们:XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable); foreach(XmlAttribute curAttribute in xml.DocumentElement.Attributes){if(curAttribute.Prefix.Equals("xmlns")){ns.AddNamespace(curAttribute.LocalName,curAttribute.Value); }} (2认同)

Tom*_*lak 19

MSDN上的文档中SelectSingleNode()获取:

注意
如果XPath表达式不包含前缀,则假定名称空间URI是空名称空间.如果您的XML包含默认命名空间,您仍必须向XmlNamespaceManager添加前缀和命名空间URI; 否则,您将无法选择节点.有关更多信息,请参阅使用XPath导航选择节点.

紧接着的示例代码是

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ab", "http://www.lucernepublishing.com");
XmlNode book = doc.SelectSingleNode("//ab:book", nsmgr);
Run Code Online (Sandbox Code Playgroud)

并不是 因为 如果 " 隐性 知识 ".;-)


小智 7

这样你就不需要指定命名空间:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("your xml");
XmlNode node = xmlDoc.SelectSingleNode("/*[local-name() = 'Compile']");
XmlNode nodeToImport = xmlDoc2.ImportNode(node, true);
xmlDoc2.AppendChild(nodeToImport);
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,有必要使用 //*[local-name 而不是 /*[local-name (2认同)