【问题标题】:LINQ to XML - Get given XElement's text content without child elements' text contentLINQ to XML - 获取给定 XElement 的文本内容,但不包含子元素的文本内容
【发布时间】:2012-05-05 08:10:14
【问题描述】:

我刚开始使用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

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

如何获取只有第二个孩子的文本内容,而没有孙子的文本内容?

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


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

【问题讨论】:

    标签: linq-to-xml


    【解决方案1】:

    如果有多个文本节点,你想做什么?例如,您可以将它们全部连接在一起:

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

    【讨论】:

    • 这让我走上了正轨。我不希望每个元素中有多个文本节点,所以我只选择第一个。我将编辑我的问题以显示与您的示例类似的解决方案。谢谢。
    • @Avery:如果您只想要第一个节点,请参阅我的编辑以获得更简单的方法。
    • 对第二个 sn-p 的轻微修正:Nodes() 被设置为方法,而不是属性,所以代码应该这样写:var textNode = xElem.Nodes().OfType&lt;XText&gt;().FirstOrDefault();
    • @JeffFerguson:已修复 - 当然,您始终可以自己进行更改。
    猜你喜欢
    • 2015-02-20
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多