Практическое руководство. Связанные вызовы метода оси (LINQ to XML)
Обычно при написании кода вы будете придерживаться схемы, по которой вызывается метод оси, после чего вызывается одна из осей метода расширений.
Существуют две оси с именем Elements
, которые возвращают коллекцию элементов: методы XContainer.Elements и Extensions.Elements. Можно сочетать эти две оси таким образом, чтобы найти все элементы с указанным именем на заданной глубине дерева.
Пример. Получение всех элементов имени
В этом примере используется и извлекается XContainer.Elements все Name
элементы во всех Address
элементахPurchaseOrder
.Extensions.Elements
В этом примере используется XML-файл XML-документа Sample XML: несколько заказов на покупку.
XElement purchaseOrders = XElement.Load("PurchaseOrders.xml");
IEnumerable<XElement> names =
from el in purchaseOrders
.Elements("PurchaseOrder")
.Elements("Address")
.Elements("Name")
select el;
foreach (XElement e in names)
Console.WriteLine(e);
Dim purchaseOrders As XElement = XElement.Load("PurchaseOrders.xml")
Dim names As IEnumerable(Of XElement) = _
From el In purchaseOrders.<PurchaseOrder>.<Address>.<Name> _
Select el
For Each e As XElement In names
Console.WriteLine(e)
Next
В примере получается следующий вывод.
<Name>Ellen Adams</Name>
<Name>Tai Yee</Name>
<Name>Cristian Osorio</Name>
<Name>Cristian Osorio</Name>
<Name>Jessica Arnold</Name>
<Name>Jessica Arnold</Name>
Такой подход оправдан, поскольку одна из реализаций оси Elements
представляет собой метод расширений IEnumerable<T> по отношению к XContainer. XElement вычисляется из XContainer, что позволяет вызвать метод Extensions.Elements по результатам вызова метода XContainer.Elements.
Пример. Получение всех элементов в определенной глубине
Иногда требуется получить все элементы на определенной глубине элемента, когда не может быть между предками. Например, в следующем документе может потребоваться получить все ConfigParameter
элементы, которые являются дочерними элементами Customer
элемента, но не ConfigParameter
дочерним элементом Root
элемента.
<Root>
<ConfigParameter>RootConfigParameter</ConfigParameter>
<Customer>
<Name>Frank</Name>
<Config>
<ConfigParameter>FirstConfigParameter</ConfigParameter>
</Config>
</Customer>
<Customer>
<Name>Bob</Name>
<!--This customer doesn't have a Config element-->
</Customer>
<Customer>
<Name>Bill</Name>
<Config>
<ConfigParameter>SecondConfigParameter</ConfigParameter>
</Config>
</Customer>
</Root>
Чтобы это реализовать, можно использовать ось Extensions.Elements следующим образом.
XElement root = XElement.Load("Irregular.xml");
IEnumerable<XElement> configParameters =
root.Elements("Customer").Elements("Config").
Elements("ConfigParameter");
foreach (XElement cp in configParameters)
Console.WriteLine(cp);
Dim root As XElement = XElement.Load("Irregular.xml")
Dim configParameters As IEnumerable(Of XElement) = _
root.<Customer>.<Config>.<ConfigParameter>
For Each cp As XElement In configParameters
Console.WriteLine(cp)
Next
В примере получается следующий вывод.
<ConfigParameter>FirstConfigParameter</ConfigParameter>
<ConfigParameter>SecondConfigParameter</ConfigParameter>
Пример. Получение элементов для XML в пространстве имен
В следующем примере показан тот же метод XML, который находится в пространстве имен. Дополнительные сведения см. в обзоре пространств имен.
В этом примере используется XML-файл SAMPLE XML: несколько заказов на покупку в пространстве имен.
XNamespace aw = "http://www.adventure-works.com";
XElement purchaseOrders = XElement.Load("PurchaseOrdersInNamespace.xml");
IEnumerable<XElement> names =
from el in purchaseOrders
.Elements(aw + "PurchaseOrder")
.Elements(aw + "Address")
.Elements(aw + "Name")
select el;
foreach (XElement e in names)
Console.WriteLine(e);
Imports <xmlns:aw="http://www.adventure-works.com">
Module Module1
Sub Main()
Dim purchaseOrders As XElement = XElement.Load("PurchaseOrdersInNamespace.xml")
Dim names As IEnumerable(Of XElement) = _
From el In purchaseOrders.<aw:PurchaseOrder>.<aw:Address>.<aw:Name> _
Select el
For Each e As XElement In names
Console.WriteLine(e)
Next
End Sub
End Module
В примере получается следующий вывод.
<aw:Name xmlns:aw="http://www.adventure-works.com">Ellen Adams</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Tai Yee</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Cristian Osorio</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Cristian Osorio</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Jessica Arnold</aw:Name>
<aw:Name xmlns:aw="http://www.adventure-works.com">Jessica Arnold</aw:Name>