Получить первый дочерний узел в XSLT с помощью local-name()
предположим, что у нас есть этот простой xml ...
<books>
<book>
<author/>
<title/>
</book>
<book>
<author/>
<title/>
</book>
</books>
Я использую этот xpath для получения элементов первого экземпляра книги.
//books[1]/*
возвращает
<author/>
<title/>
и это отлично работает, но я должен заставить его работать с помощью local-name(). Я пробовал следующее, Но ничего из этого не работает...
//*[local-name()='books']/*
это возвращает повторяющиеся элементы автора и заголовка, не хорошо, мне нужны только от первого ребенка
//*[local-name()='books'][0]/*
это не вернуть ничего
в основном, я хочу создать CSV-файл, поэтому первая строка в выходных данных будет заголовком с перечислением имен атрибутов книги, за которыми следуют произвольные значения данных. Мне нужно только заставить работать часть заголовка.
author,title
john,The End is Near
sally,Looking for Answers
3 ответов
выражение пути, которое вы говорите, работает для вас
//books[1]/*
генерирует список всех дочерних узлов первого (и только в этом случае) вхождения любого узла
/books/*
который возвращает два узла
трудно знать, что вам нужно, если вы всегда обращаетесь local-name
к корневому узлу тогда вам не нужно знать его имя и доступ к нему только /*
, так что вы хотели просто
/*/*[1]
однако для доступа к первому дочернему узлу узла
//*[local-name()='books']/*[1]
вы должны быть осторожны, чтобы ограничить свой контекст как можно больше, начиная выражение XPath с //
будет принудительно искать весь документ, что бессмысленно и требует много времени, если рассматриваемый узел всегда находится на корень.
это FAQ -- XPath []
оператор имеет более высокий приоритет (приоритет), чем //
псевдо-оператора.
так:
//someElemName[1]
выбирает каждый элемент с именем someElemName
это первый дочерний элемент его родителя - и, в зависимости от XML-документа, может быть несколько таких элементов.
чтобы изменить это, необходимо использовать скобки.
использовать:
(//*[local-name() = 'book'])[1]/*
также Примечание!--10-->: В XPath позиции основаны на 1, а не на 0.
проверка на основе XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"(//*[local-name() = 'book'])[1]/*"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к следующему XML-документу:
<books>
<book num="1">
<author num="1"/>
<title num="1"/>
</book>
<book num="2">
<author num="2"/>
<title num="2"/>
</book>
</books>
нужные узлы выбираются и копируются на выход:
<author num="1"/>
<title num="1"/>
Я должен удовлетворить те же проблемы. Я решил так:
//*[local-name()='MYNODENAME' and position()=X]
хорошего дня.