如何获取XElement的值而不是所有子节点的值?

时间:2010-11-22 23:17:31

标签: c# xelement

示例xml:

<parent>
<child>test1</child>
<child>test2</child>
</parent>

如果我查找parent.Value,其中parent是XElement,我得到“test1test2”。 我期待的是“”。 (因为没有文字/值。

我应该寻找XElement的哪些属性?

5 个答案:

答案 0 :(得分:25)

<parent>元素中查找文本数据时,您应该查找NodeType属性等于XmlNodeType.Text的子节点。这些节点的类型为XText。以下示例说明了这一点:

var p = XElement
    .Parse("<parent>Hello<child>test1</child>World<child>test2</child>!</parent>");

var textNodes = from c in p.Nodes()
                where c.NodeType == XmlNodeType.Text
                select (XText)c;

foreach (var t in textNodes)
{
    Console.WriteLine(t.Value);
}

更新:如果你想要的只是第一个Text节点,如果有的话,这是一个使用LINQ方法调用而不是查询理解语法的例子:

var firstTextNode = p.Nodes().OfType<XText>().FirstOrDefault();
if (firstTextNode != null)
{
    var textValue = firstTextNode.Value;
    ...do something interesting with the value
}

注意:在此方案中使用First()FirstOrDefault()的效果将比Count() > 0更高。 Count始终枚举整个集合,而FirstOrDefault()只会枚举,直到找到匹配项。

答案 1 :(得分:8)

您可以在XText中连接所有parent个节点的值:

XElement parent = XElement.Parse(
    @"<parent>Hello<child>test1</child>World<child>test2</child>!</parent>");

string result = string.Concat(
    parent.Nodes().OfType<XText>().Select(t => t.Value));

// result  ==  "HelloWorld!"

进行比较:

// parent.Value  ==  "Hellotest1Worldtest2!"

// (parent.HasElements ? "" : parent.Value)  ==  ""

答案 2 :(得分:3)

令人惊讶的是,微软某处的编码器认为将所有文本值作为连接和不受限制的字符串返回会很有用。幸运的是,另一位MS开发人员编写了一个XElement扩展来返回他们称之为文本节点here的“浅值”。对于那些通过点击链接获得帮助的人来说,功能如下......

    public static string ShallowValue(this XElement element)
    {
        return element
               .Nodes()
               .OfType<XText>()
               .Aggregate(new StringBuilder(),
                          (s, c) => s.Append(c),
                          s => s.ToString());
    }

你这样称呼它,因为它也给你所有的空白(或者,想想它,你可以在扩展中修剪它,无论如何)

// element is a var in your code of type XElement ...
string myTextContent = element.ShallowValue().Trim();

答案 3 :(得分:1)

msdn说:

  

包含此元素的所有文本内容的String。如果有多个文本节点,它们将被连接。

所以行为是可以预期的。

您可以通过以下方式解决问题:

string textContent = parent.HasElements ? "" : parent.Value;

答案 4 :(得分:1)

// Create the XElement
XElement parent = XElement.Parse(
    @"<parent>Hello<child>test1</child>World<child>test2</child>!</parent>");

// Make a copy
XElement temp=new XElement(parent);

// remove all elements but root
temp.RemoveNodes();

// now, do something with temp.value, e.g.
Console.WriteLine(temp.value);