LINQ to XML - Get given XElement's text conten

2019-06-21 21:13发布

I have just started using LINQ to XML, and I am having trouble getting the text contents of a given XElement without getting the text contents of all the child elements as well.

So for example, if I have the following XML document:

<?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>

And I use the following Test method:

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);
    }
}

Then I get two lines on output:

    value 1
    value 2value A

The first line shows the content of the first child - this is okay. The second line however shows not only the text content of the first child, but also any decendants of that child.

How can I get the text content of just the second child without the grandchild's text content as well?

Also note that the sample is just a simple example to illustrate what I am doing, and in production I will not necessarily know what the child elements are called (if any), but I should be able to get the element I need to get the text content from.


Jon Skeet's answer helped with the solution. Just replace the foreach loop with the following to select text XNodes rather than the XElement's value:

...
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());
}

标签: linq-to-xml
1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-06-21 21:49

What do you want to do if there are multiple text nodes? For example, you could join them all together:

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

EDIT: If you only want a single element, it's easier than you've shown:

var textNode = xElem.Nodes.OfType<XText>().FirstOrDefault();
if (textNode != null)
{
    Console.WriteLine(textNode.Value);
}
查看更多
登录 后发表回答