Функция last()
XPath может использоваться для поиска последнего из набора узлов. Таким образом, последний <PN>
узел с атрибутом N
, имеющий значение @P1
, будет иметь вид:
//PN[@N='@P1'][position() = last()]
Код .NET будет зависеть от того, какой XML API вы используете: XmlDocument
, XPathDocument
или LINQ to XML (XDocument
). (Подход с XmlReader
заключается в загрузке в одну из трех и последующем использовании.)
Редактировать (на основе комментария) Возвращать <F>
потомка последнего <PN>
с атрибутом, как указано выше, где xDoc
является экземпляром XmlDocument
:
var foundNode = xDoc.SelectSingleNode("//PN[@N='@P1'][position() = last()]/TM/JB/F");
Редактировать # 2 (на основе другого комментария) : вернуть последний <PN>
, где каждый <DT>
может содержать несколько <DT>
элементов 1 по всем <DT>
элементам.
Проверка этого с использованием лучшего образца XML (см. Ниже) с использованием XmlElement.SelectNodes
, а затем итерация по возвращенному набору узлов показала, что был найден нужный узел, он просто не был первым и поэтому не возвращается SelectSingleNode
. Это подсказка: предикат last()
применялся в каждом совпадении //PN[@N='@P1']
. Быстрая смена приоритета - все, что было нужно:
(//PN[@N='@P1'])[last()]
1 Для дальнейшего использования, если возможно несколько элементов, укажите хотя бы два в образце, в противном случае читатели примут только единичные экземпляры. Также удалите все узлы (например, дочерние), которые не нужны:
Образец XML, который я использовал для тестирования (добавлены атрибуты x, чтобы упростить идентификацию элемента, выбранного во время тестирования):
<UN N='@U1'>
<DT N='24/06/2011'>
<PN N='@P1' x='#1'/>
<PN N='@P1' x='#2'/>
<PN N='@P2' x='#3'/>
</DT>
<DT N='24/06/2011'>
<PN N='@P1' x='#4'/>
<PN N='@P1' x='#5'/>
<PN N='@P2' x='#6'/>
</DT>
<DT N='24/06/2011'>
<PN N='@P3' x='#7'/>
<PN N='@P4' x='#8'/>
<PN N='@P5' x='#9'/>
</DT>
</UN>