2010-02-26 71 views
52

我有這樣的代碼:使用LINQ與XML命名空間爲XML

/*string theXml = 
@"<Response xmlns=""http://myvalue.com""><Result xmlns:a=""http://schemas.datacontract.org/2004/07/My.Namespace"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><a:TheBool>true</a:TheBool><a:TheId>1</a:TheId></Result></Response>";*/ 

string theXml = @"<Response><Result><TheBool>true</TheBool><TheId>1</TheId></Result></Response>"; 

XDocument xmlElements = XDocument.Parse(theXml); 

var elements = from data in xmlElements.Descendants("Result") 
       select new { 
          TheBool = (bool)data.Element("TheBool"), 
          TheId = (int)data.Element("TheId"), 
          }; 

foreach (var element in elements) 
{ 
    Console.WriteLine(element.TheBool); 
    Console.WriteLine(element.TheId); 
} 

當我使用theXml的第一個值,結果爲空,而用第二個,我有良好的價值觀......

如何使用Linq到XML與xmlns值?

回答

79

LINQ到XML方法如DescendantsElement採取XName作爲參數。從stringXName的轉換會自動發生。您可以通過在DescendantsElement調用中的字符串前添加XNamespace來解決此問題。小心,因爲你有兩個不同的命名空間在工作。

 

string theXml = 
       @"true1"; 

      //string theXml = @"true1"; 

    XDocument xmlElements = XDocument.Parse(theXml); 
    XNamespace ns = "http://myvalue.com"; 
    XNamespace nsa = "http://schemas.datacontract.org/2004/07/My.Namespace"; 
    var elements = from data in xmlElements.Descendants(ns + "Result") 
      select new 
       { 
        TheBool = (bool) data.Element(nsa + "TheBool"), 
        TheId = (int) data.Element(nsa + "TheId"), 
       }; 

    foreach (var element in elements) 
    { 
     Console.WriteLine(element.TheBool); 
     Console.WriteLine(element.TheId); 
    } 
 

注意在Elements

+1

很棒,工作:)!非常感謝 – Tim 2010-02-26 09:58:12

+18

xmlElements.Descendants(xmlElements.Root.GetDefaultNamespace()+「Result」)也可以工作。 – 2010-10-22 20:10:37

23

您可以將XName的名稱空間傳遞給Descendants()Element()。將字符串傳遞給Descendants()時,它將隱式轉換爲不帶名稱空間的XName。

要在命名空間中創建的XName,您創建的XNamespace和它串聯的元素本地名稱(字符串)。

XNamespace ns = "http://myvalue.com"; 
XNamespace nsa = "http://schemas.datacontract.org/2004/07/My.Namespace"; 

var elements = from data in xmlElements.Descendants(ns + "Result") 
        select new 
           { 
            TheBool = (bool)data.Element(nsa + "TheBool"), 
            TheId = (int)data.Element(nsa + "TheId"), 
           }; 

還有用於經由從字符串的隱式轉換命名空間創建的XName的簡寫形式。

var elements = from data in xmlElements.Descendants("{http://myvalue.com}Result") 
        select new 
           { 
            TheBool = (bool)data.Element("{http://schemas.datacontract.org/2004/07/My.Namespace}TheBool"), 
            TheId = (int)data.Element("{http://schemas.datacontract.org/2004/07/My.Namespace}TheId"), 
           }; 

或者,您可以針對XEl​​ement進行查詢。 Name.LocalName

var elements = from data in xmlElements.Descendants() 
        where data.Name.LocalName == "Result" 
+0

LocalName在我的intellissense中不存在 – Tim 2010-02-26 09:57:12

+2

從+運算符到xname的轉換是灰熊,恐怖和徹底的憎惡。 MS在想什麼?據推測,它在引擎蓋下使用了一個表達式 - 這讓我感覺不舒服。 – Gusdor 2013-08-06 14:06:25

+0

{簡寫}爲+1。我不知道! – 2014-05-13 01:14:27

0

使用在Descendants和NSA納秒我發現下面的代碼以做工精細閱讀與命名空間屬性在VB.NET:

MyXElement.Attribute(MyXElement.GetNamespaceOfPrefix("YOUR_NAMESPACE_HERE") + "YOUR_ATTRIB_NAME") 

希望這有助於有人在路上。

0

我有一個XML文檔的頂部列出幾個命名空間,我真的不關心哪些元素是從哪個命名空間。我只想通過他們的名字獲得元素。我已經寫了這個擴展方法。

/// <summary> 
    /// A list of XElement descendent elements with the supplied local name (ignoring any namespace), or null if the element is not found. 
    /// </summary> 
    public static IEnumerable<XElement> FindDescendants(this XElement likeThis, string elementName) { 
     var result = likeThis.Descendants().Where(ele=>ele.Name.LocalName==elementName); 
     return result; 
    }