示例xml:
<parent>
<child>test1</child>
<child>test2</child>
</parent>
如果我使用XElement的parent.Value属性,我会得到"test1test2"。
但我期望得到的是""(因为没有文本/值)。我应该查找XElement的哪个属性?
在查找<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);
}
更新: 如果您只想获取第一个文本节点(如果有的话),这里有一个使用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()
只会枚举直到找到匹配项。
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();
Value
应该是当前元素。ToString()
或 some other value
应该是当前元素加上子元素。 - Pure.Kromeparent
节点中所有XText
节点的值连接起来: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) == ""
Concat
无法给出期望的结果,因为它不会连接列表中的字符串,而是其参数的“类型名称”,在此处为字符串的IEnumerable
。相反,你可能需要使用string.Join("", element.Nodes().OfType<XText>().Select(t => t.Value).ToArray());
。 - Evariste// 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);
msdn说:
一个包含此元素所有文本内容的字符串。如果有多个文本节点,则它们将被连接。
因此,这种行为是可以预期的。
您可以通过执行以下操作来解决问题:
string textContent = parent.HasElements ? "" : parent.Value;
<parent>Hello<child>test1</child>World<child>test2</child>!</parent>
- dtb
XCData
节点找到。你可以轻松地扩展查询以返回文本和CData。 - Peter Lillevold