首頁 > 後端開發 > XML/RSS教程 > 詳解XML命名空間(XML Namespaces)介紹以及節點讀取方法的範例程式碼

詳解XML命名空間(XML Namespaces)介紹以及節點讀取方法的範例程式碼

黄舟
發布: 2017-03-21 16:39:28
原創
2695 人瀏覽過

XML 命名空間提供避免元素命名衝突的方法。

命名衝突

在 XML 中,元素名稱是由開發者定義的,當兩個不同的文件使用相同的元素名稱時,就會發生命名衝突。

這個XML 文件攜帶著某個表格中的信息:

   <tr>
   <td>Apples</td>
   <td>Bananas</td>
   </tr>
登入後複製

這個XML 文件攜帶有關桌子的信息(一件家具):

   <name>African Coffee Table</name>
   <width>80</width>
   <length>120</length>
登入後複製

假如這兩個XML 文件被一起使用,由於兩個文件都包含帶有不同內容和定義的

元素,就會發生命名衝突。

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>
登入後複製

現在,命名衝突不存在了,這是由於兩個文件都使用了不同的名稱來命名它們的

元素()。

透過使用前綴,我們創建了兩種不同類型的

元素。

使用命名空間(Namespaces)

這個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>
登入後複製

與僅使用前綴不同,我們為

標籤添加了一個xmlns 屬性,這樣就為前綴賦予了一個與某個命名空間相關聯的限定名稱。

XML Namespace (xmlns) 屬性

XML 命名空間屬性被放置於元素的開始標籤之中,並使用以下的語法:

xmlns:namespace-prefix="namespaceURI"
登入後複製

當命名空間被定義在元素的開始標籤中時,所有帶有相同前綴的子元素都會與同一個命名空間相關聯。

註解:用於標示命名空間的位址不會被解析器用於尋找資訊。其惟一的作用是賦予命名空間一個惟一的名稱。不過,許多公司常常會作為指標來使用命名空間指向實際存在的網頁,而這個網頁包含關於命名空間的資訊。

統一資源識別碼(Uniform Resource Identifier (URI))

#統一資源識別碼是一串可以標識網際網路資源的字元。最常用的 URI 是用來標示因特網域名位址的統一資源定位器(URL)。另一個不那麼常用的 URI 是統一資源命名(URN)。在我們的例子中,我們只使用 URL。

預設的命名空間(Default Namespaces)

為元素定義預設的命名空間可以讓我們省去在所有的子元素中使用前綴的工作。

請使用下面的語法:

xmlns="namespaceURI"
登入後複製

這個XML 文件攜帶著某個表格中的信息:

<tr> <td>Apples</td> <td>Bananas</td> </tr>
登入後複製

此XML 文件攜帶著有關一件家具的信息:


   <name>African Coffee Table</name>
   <width>80</width>
   <length>120</length>
(转原文http://www.cnblogs.com/mgen/archive/2011/05/24/2056025.html)
登入後複製

眾所周知,XmlDocument可以進行XPath查詢,但實際上這裡所說的XPath查詢僅限於沒有命名空間(沒有xmlns屬性)的XML,一旦遇到有命名空間的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
登入後複製

意思就是如果XPath表達式沒有加上前綴(如a:b中前綴是a),那麼所查詢節點(注意屬性也可以是節點)的命名空間URI就應該是空值(也是預設值),否則XPath不會回傳結果。

上面的XML, 因為節點a和b都有命名空間值,自然XPath查詢不會有結果。

(上面英文也提到如果節點有預設命名空間,那麼還得手動在XmlNamespaceManager中加入前綴和命名空間值,這個在後面會講的)

在看解決方案前,首先需要能夠辨識XML命名空間,當然辨識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命名空間沒有問題,那麼後面的操作就相當簡單了,你需要記住:在XmlDocument中用XPath查詢某一節點時,只要它的命名空間值不是空值,那麼你必須給它一個前綴, 用這個前綴代表這個節點的命名空間值!這些前綴是透過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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板