2012-04-24 97 views
4

我正在使用linq-to-xml來搜索元素。Linq-to-XML獲取具有名稱空間的元素

var doc = XDocument.Load(reader); 
        var ns = doc.Root.Attribute("xmlns").Value; 
        var result = (from u in doc.Descendants(XName.Get("MyElement", ns)) 

我需要擺脫使用XName.Get,每當我嘗試在xml中找到一個元素。我如何設置一個默認的命名空間XDocument,以便它不會打擾搜索時。

問候。

回答

5

這裏是忽略默認命名的一種方式,如果你真的想這樣做:

 XDocument doc; 
     using (XmlTextReader xr = new XmlTextReader("input.xml")) 
     { 
      xr.Namespaces = false; 
      doc = XDocument.Load(xr); 
     } 
     foreach (XElement bar in doc.Descendants("bar")) 

但我會建議接受命名空間的XML的存在和重要性,以及使用的XName和的XNamespace對象LINQ到XML提供與他們一起工作。

+0

是的,我同意命名空間的重要性,但在我的情況下,我的xml文檔元素屬於我已知的單個命名空間。所以我真的不需要在搜索元素時一次又一次地傳遞它。 – 2012-04-24 19:25:43

1

不能這樣做:

doc = XDocument.Load(reader); 
var ns = doc.Root.Attribute("xmlns").Value; 
var result = from u in doc.Descendants.Elements(ns+"MyElement").Select(c=>c.Value); 
+0

再次,這將需要ns被連接,並使代碼有點模糊。我們不能避免ns? – 2012-04-24 13:03:29

4

我需要擺脫使用XName.Get的,每當我試圖找到在XML元素。我如何設置一個默認的命名空間XDocument,以便它不會打擾搜索時。

你不能 - 但也有其他兩個選項:

  • 使用+(XNamespace, string)操作:

    doc.Descendants(ns + "MyElement") 
    
  • 剛剛創建XName值一次,然後引用它們你的查詢,例如

    XName myElementName = ns + "MyElement"; 
    ... 
    doc.Descendants(myElementName); 
    

理想情況下,你不會動態創建的命名空間呢 - 難道你不知道應該尋找在命名空間?如果這樣做,可以使用適當的XName值創建私有靜態只讀字段。

+0

所以沒有辦法說這個節點中的所有元素都屬於這個命名空間,這將允許我通過名稱正確地搜索元素? – 2012-04-24 13:08:44

+0

@Shoaib謝赫:你只能用'XName'搜索,而不能用字符串搜索。當您通過從字符串轉換來創建'XName'時,會創建一個沒有名稱空間的'XName'。 – 2012-04-24 13:10:38

+0

在將它作爲XDocument使用之前,您可以從xml的文本中刪除命名空間。 – 2012-04-24 13:12:16

1

您也可以使用LocalName,它使LINQ錯誤化,但完成工作。 (在這種情況下從MSBuild項目文件獲取屬性)。

var imports = from i in doc.Root.Elements() 
       where i.Name.LocalName == "Import" 
       from p in i.Attributes() 
       where p.Name.LocalName == "Project" 
       select p.Value; 

我喜歡做這樣的事情是,它留下的原始形式的XML,但它意味着給別人的東西有趣的是怎麼回事。將「LocalName」放在LINQ表達式中就是一種自我記錄的黑客行爲。

如果代碼分離,關閉XmlTextReader中的名稱空間很容易被忽略。