Как найти потомков дочернего элемента (XPath-LINQ to XML)
В этом разделе рассказывается, как возвращать элементы-потомки дочерних элементов с определенным именем.
Выражение XPath:
./Paragraph//Text/text()
Пример
В этом примере имитируются проблемы извлечения текста из XML-представления документа текстового редактора. В нем сначала выделяются все элементы Paragraph, а затем в нем выделяются все элементы-потомки Text каждого элемента Paragraph. В этом примере элементы-потомки Text элемента Comment не выделяются.
XElement root = XElement.Parse(
@"<Root>
<Paragraph>
<Text>This is the start of</Text>
</Paragraph>
<Comment>
<Text>This comment is not part of the paragraph text.</Text>
</Comment>
<Paragraph>
<Annotation Emphasis='true'>
<Text> a sentence.</Text>
</Annotation>
</Paragraph>
<Paragraph>
<Text> This is a second sentence.</Text>
</Paragraph>
</Root>");
// LINQ to XML query
string str1 =
root
.Elements("Paragraph")
.Descendants("Text")
.Select(s => s.Value)
.Aggregate(
new StringBuilder(),
(s, i) => s.Append(i),
s => s.ToString()
);
// XPath expression
string str2 =
((IEnumerable)root.XPathEvaluate("./Paragraph//Text/text()"))
.Cast<XText>()
.Select(s => s.Value)
.Aggregate(
new StringBuilder(),
(s, i) => s.Append(i),
s => s.ToString()
);
if (str1 == str2)
Console.WriteLine("Results are identical");
else
Console.WriteLine("Results differ");
Console.WriteLine(str2);
Dim root As XElement = _
<Root>
<Paragraph>
<Text>This is the start of</Text>
</Paragraph>
<Comment>
<Text>This comment is not part of the paragraph text.</Text>
</Comment>
<Paragraph>
<Annotation Emphasis='true'>
<Text> a sentence.</Text>
</Annotation>
</Paragraph>
<Paragraph>
<Text> This is a second sentence.</Text>
</Paragraph>
</Root>
' LINQ to XML query
Dim str1 As String = _
root.<Paragraph>...<Text>.Select(Function(ByVal s) s.Value). _
Aggregate( _
New StringBuilder(), _
Function(ByVal s, ByVal i) s.Append(i), _
Function(ByVal s) s.ToString())
' XPath expression
Dim str2 As String = DirectCast(root.XPathEvaluate("./Paragraph//Text/text()"), IEnumerable) _
.Cast(Of XText)().Select(Function(ByVal s) s.Value) _
.Aggregate( _
New StringBuilder(), _
Function(ByVal s, ByVal i) s.Append(i), _
Function(ByVal s) s.ToString())
If str1 = str2 Then
Console.WriteLine("Results are identical")
Else
Console.WriteLine("Results differ")
End If
Console.WriteLine(str2)
Этот пример выводит следующие данные.
Results are identical
This is the start of a sentence. This is a second sentence.