XML 名前空間 は、要素の名前の競合を回避する方法を提供します。
XML では、要素名は開発者によって定義されます。2 つの異なるドキュメントが同じ要素名を使用すると、名前の競合が発生します。
この XML ドキュメントはテーブル内の情報を伝えます:
<tr> <td>Apples</td> <td>Bananas</td> </tr>
この XML ドキュメントはテーブル (家具) に関する情報を伝えます:
<name>African Coffee Table</name> <width>80</width> <length>120</length>
これら 2 つの XML ドキュメントが一緒に使用される場合、両方のドキュメントに含まれるため、< の場合に名前の競合が発生します。 ;table> 要素には異なる内容と定義があります。
XML パーサーは、そのような競合を処理する方法を決定できません。
このドキュメントはテーブル内の情報を伝えます:
<h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr>
この XML ドキュメントは家具に関する情報を伝えます:
<f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length>
現在、名前の競合は存在しません。これは両方のドキュメントが原因です。
この XML ドキュメントは、家具に関する情報を伝えます:
ご存知のとおり、XmlDocument は XPath クエリを実行できます。 ただし、実際には、ここで説明する XPath クエリは、名前空間のない XML (xmlns 属性なし) に限定されます。名前空間のある XML が検出されると、対応する XPath クエリは結果を返しません。
たとえば、次の XML
<a xmlns="mgen.cnblogs.com"> <b>ccc</b> </a>
XPath クエリ /a/b は null を返し、xmlns がない場合はノード b が返されます。
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
は、XPathexpression にプレフィックスが付いていない場合 (たとえば、a:b のプレフィックスが a である場合)、クエリされたノードの名前空間 URI (属性がノードである場合もあることに注意してください) が空である必要があることを意味します(デフォルト値も)、そうでない場合、XPath は結果を返しません。
上記の XML では、ノード a と b に名前空間値があるため、当然ながら XPath クエリには結果がありません。
(上記の英語では、ノードにデフォルトの名前空間がある場合、プレフィックスと名前空間の値を XmlNamespaceManager に手動で追加する必要があるとも述べています。これについては後で説明します)
解決策を検討する前に、まず次のことを行う必要があります。もちろん、XML 名前空間の値を識別するのは非常に簡単です。次の XML を参照してください (この XML は次の手順でも使用されます)
<?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>
そのすべての XML ノードの名前空間は次のとおりです。次のように:
<?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>
識別された場合 XML 名前空間には問題がないため、その後の操作は非常に簡単です: XPath を使用して XmlDocument 内のノードをクエリする場合、その名前空間が存在する限り。 value が null ではない場合は、接頭辞を付ける必要があります。この接頭辞を使用して、このノードの名前空間値を表します。これらのプレフィックスは、XmlNamespaceManager クラスを通じて追加されます。使用する場合は、XmlNamespaceManager を SelectNodes または SelectSingleNode に渡すだけです。これが、上記で「ノードにデフォルトの名前空間がある場合、プレフィックスと名前空間の値を 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
以上がXML名前空間(XML Namespaces)の詳しい説明とノード読み取り方法のサンプルコードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。