2010-02-26 50 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; 
    }