XML Namespace Provides a way to avoid element naming conflicts.
In XML, element names are defined by developers. When two different documents use the same element name, a naming conflict occurs.
This XML document carries information in a table:
<tr> <td>Apples</td> <td>Bananas</td> </tr>
This XML document carries information about a table (a piece of furniture):
<name>African Coffee Table</name> <width>80</width> <length>120</length>
If these two XML documents are used together, and a naming conflict occurs because both documents contain
This XML document carries information about a piece of furniture:
As we all know, XmlDocument can perform XPathquery, but in fact the XPath query mentioned here is limited to XML without namespace (no xmlns attribute), once When encountering XML with namespace, the corresponding XPath query will have no results.
For example, the following XML
<a xmlns="mgen.cnblogs.com"> <b>ccc</b> </a>
XPath query /a/b will return null, and if there is no xmlns, node b will be returned.
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 any nodes selected
means that if the XPathexpression is not prefixed (for example, the prefix in a:b is a), then the namespace URI of the queried node (note that the attribute can also be a node) is Should be empty (also the default value), otherwise XPath will not return results.
In the above XML, because nodes a and b have namespace values, naturally the XPath query will have no results.
(The above English also mentioned that if the node has a default namespace, then you have to manually add the prefix and namespace value to the XmlNamespaceManager, which will be discussed later)
Before looking at the solution, First of all, you need to be able to identify the XML namespace. Of course, it is still very easy to identify the XML namespace value. Refer to the following XML (this XML will also be used in the later program)
<?xmlversion="1.0" encoding="utf-8"?> <rootxmlns="dotnet" xmlns:w="wpf"> <a>data in a</a> <w:b>data in b</w:b> <cxmlns="silverlight"> <w:d> <e>data in e</e> </w:d> </c> </root>
The namespace of all its XML nodes is as follows Shown:
<?xmlversion="1.0" encoding="utf-8"?> <rootxmlns="dotnet" xmlns:w="wpf"> <!-- xmlns: dotnet --> <a>data in a</a> <!-- xmlns: dotnet --> <w:b>data in b</w:b> <!-- xmlns: wpf --> <cxmlns="silverlight"> <!-- xmlns: silverlight --> <w:d> <!-- xmlns: wpf --> <e>data in e</e> <!-- xmlns: silverlight --> </w:d> </c> </root>
If there is no problem in identifying the XML namespace, then the subsequent operations are quite simple. You need to remember: In XmlDocument When using XPath to query a node, as long as its namespace value is not null, you must give it a prefix . Use this prefix to represent the namespace value of this node! These prefixes are added through the XmlNamespaceManager class. When using, just pass the XmlNamespaceManager into SelectNodes or SelectSingleNode. This is why it is said above that "If the node has a default namespace, then you have to manually add the prefix and namespace value to the XmlNamespaceManager".
另外构造一个XmlNamespaceManager需要XmlNameTable对象,这个对象可以从XmlDocument.NameTable和XmlReader.NameTable属性中得到。
下面我们步入代码,比如说查询上面XML中的节点e,分析位置节点e位于:root->c->d->e,然后将所需命名空间值加入到 XmlNamespaceManager中(前缀名称无所谓,只要在XPath一致即可),查询即可成功,如下代码:
/* * 假设上面XML文件在C:\a.txt中 * 下面代码会查询目标节点e,并输出数据:data in e * */ var xmlDoc =newXmlDocument(); xmlDoc.Load(@"C:\a.txt"); //加入命名空间和前缀 var xmlnsm =newXmlNamespaceManager(xmlDoc.NameTable); xmlnsm.AddNamespace("d", "dotnet"); xmlnsm.AddNamespace("s", "silverlight"); xmlnsm.AddNamespace("w", "wpf"); var node = xmlDoc.SelectSingleNode("/d:root/s:c/w:d/s:e", xmlnsm); Console.WriteLine(node.InnerText); //输出:data in e
The above is the detailed content of Detailed explanation of XML Namespaces (XML Namespaces) and sample code for node reading methods. For more information, please follow other related articles on the PHP Chinese website!