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 ?
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);
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\". ;-)
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.
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);