XmlDocument.SelectSingleNode and xmlNamespace issue

不问归期 提交于 2019-12-24 09:49:47

问题


I'm loading a string to an XML document that contains the following structure :

<?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>

then im loading all into xmldocument :

XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(Xml);

then the following problem occurs :

XmlNode Node = xmldoc.SelectSingleNode("//Compile"); // return null

when i remove the xmlns attribute from the root element(Project) its working fine, how can i improve my SelectSingleNode to return the relevant element ?


回答1:


You should use an XmlNamespaceManager in your call to SelectSingleNode():

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



回答2:


Taken right from the documentation of SelectSingleNode() on the MSDN:

Note
If the XPath expression does not include a prefix, it is assumed that the namespace URI is the empty namespace. If your XML includes a default namespace, you must still add a prefix and namespace URI to the XmlNamespaceManager; otherwise, you will not get a node selected. For more information, see Select Nodes Using XPath Navigation.

And the immediately following sample code is

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

It's not as if this would be "hidden knowledge". ;-)




回答3:


Since the 'ItemGroup' may have multiple 'Compile' children, and you specifically want the 'Compile' children of 'Project/ItemGroup', the following will return all of the desired 'Compile' children and no others:

XmlDocument projectDoc = new XmlDocument();
projectDoc.Load(projectDocPath);
XmlNamespaceManager ns = new XmlNamespaceManager(projectDoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlNodeList xnList = projectDoc.SelectNodes(@"/msbld:Project/msbld:ItemGroup/msbld:Compile", ns);

Note that the 'msbld:' namespace specification needs to precede each node level.




回答4:


This way you don't need to specify namespace:

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


来源:https://stackoverflow.com/questions/47829282/how-to-get-xml-tag-which-is-in-dataset1-tagc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!