2012-04-24 32 views
4

我刚开始使用LINQ to XML,和我遇到了麻烦给定的XElement的文本内容没有得到所有的子元素的文本内容,以及。的LINQ to XML - 获取给定无子元素的文本内容的XElement的文本内容

因此,举例来说,如果我有下面的XML文档:

<?xml version="1.0" encoding="utf-8" ?> 
<root xmlns="example.org/rootns">This is root value 
    <children> 
     <child name='child 1'>value 1</child> 
     <child name='child 2'>value 2 
      <grandchild name='grandchild A'>value A</grandchild> 
     </child> 
    </children> 
</root> 

而且我用下面的测试方法:

private static void Test() 
{ 
    string xString = @"<?xml version=""1.0"" encoding=""utf-8"" ?><root xmlns=""example.org/rootns"">This is root value<children><child name='child 1'>value 1</child><child name='child 2'>value 2<grandchild name='grandchild A'>value A</grandchild></child></children></root>"; 

    var xDoc = XDocument.Parse(xString); 

    XNamespace ns = @"example.org/rootns"; 
    string elemName = "child"; 

    var xElems = from e in xDoc.Descendants(ns + elemName) 
       select e; 

    foreach (var xElem in xElems) 
    { 
     Console.WriteLine(xElem.Value); 
    } 
} 

然后我得到的输出两行:

value 1 
    value 2value A 

,第一行显示的第一个孩子的内容 - 这是好的。然而,第二行不仅显示第一个孩子的文本内容,还显示该孩子的任何后代。

我怎样才能得到公正的第二个孩子没有孙子的文本内容的文本内容呢?

另请注意,示例只是一个简单的例子来说明我在做什么,在生产中我不一定知道子元素被称为(如果有的话),但我应该能够得到元素I需要从中获取文本内容。


Jon Skeet的回答对解决方案有所帮助。只需用以下内容替换foreach循环选择文本XNodes而非的XElement的值:

... 
foreach (var xElem in xElems) 
{ 
    var values = from n in xElem.Nodes() 
       where n.NodeType == System.Xml.XmlNodeType.Text 
       select n; 

    if (values != null && values.Count() > 0) 
     Console.WriteLine(values.First()); 
} 

回答

4

你要什么做的,如果有多个文本节点?例如,你可以加入他们一起:

var text = string.Join("", element.Nodes.OfType<XText>().Select(x => x.Value)); 

编辑:如果你只想要一个单一的元素,这是很容易,你已经证明:

var textNode = xElem.Nodes.OfType<XText>().FirstOrDefault(); 
if (textNode != null) 
{ 
    Console.WriteLine(textNode.Value); 
} 
+0

这让我在正确的轨道上。我不希望每个元素中都有多个文本节点,所以我只是先拿出第一个。我将编辑我的问题以显示类似于您的示例的解决方案。谢谢。 – Avery 2012-04-24 17:15:58

+0

@Avery:如果您只想要第一个节点,请参阅我的编辑以获得更简单的方法。 – 2012-04-24 17:28:30

+0

更好,谢谢。 – Avery 2012-04-24 18:16:57