У меня есть документ, который смотрит что-то как
<root>
<element>
<subelement1 />
<subelement2 />
</element>
<element>
<subelement2 />
<subelement1 />
</element>
</root>
В моем XSLT покрывают в контексте /element[2]/[someNode]
Я хочу получить число, которое представляет расстояние /element[1]/[someNode]
(т.е., количество предыдущих одноуровневых элементов /element1/[someNode]
). Например, в контексте /element[2]/subelement1
Я хотел бы иметь некоторый способ получить номер 2, расстояние от /element[1]
кому: /element[1]/subelement2
. Мне только когда-либо нужно расстояние данного имени узла от первой инстанции <element>
.
Интуитивно я думал, что мог создать это как
<xsl:variable name="nodename" select="name()" />
<xsl:value-of select="/element[1]/$nodename/preceding-sibling::*" />
но к сожалению этот лист не компилирует. То, чего я пытаюсь достигнуть возможный в XSLT?
Вы не можете использовать переменную XSLT в качестве оси оператора XPATH, но можете использовать ее в фильтре предикатов. Итак, если вы должны сопоставить любой элемент (например, *
), а затем ограничить его элементами, имя () которых равно значению, хранящемуся в вашей переменной (например, * [name () = $ nodename]
) XPATH будет действительным.
Создаваемый вами XPATH должен возвращать значение соответствующего элемента. Если вы хотите вернуть, сколько элементов соответствует этому шаблону, вы можете использовать функцию count ()
.
В вашем примере XML есть элемент документа
, но ваш XPATH не включает
.
Это возвращает количество предшествующих одноуровневых элементов с использованием переменной, назначенной контекстным узлом:
<xsl:variable name="nodename" select="name()" />
<xsl:value-of select="count(/root/element[1]/*[name()=$nodename]/preceding-sibling::*)" />
Вы можете исключить переменную и просто использовать:
<xsl:value-of select="count(/root/element[1]/*[name()=name(current())]/preceding-sibling::*)" />
* [name () = $ nodename]
может быть тем, что вы хотите вместо $ nodename
, но тогда вам лучше определить две переменные со значением local-name () и namespace- uri () и проверьте, например, * [local-name () = $ localname и namespace-uri () = $ namespaceuri]
, чтобы иметь безопасный способ выбора элементов в пространстве имен.
Создать xpath, к сожалению, невозможно. XPath компилируются статически; вы не можете сгенерировать их на лету (или, если вы это сделаете, это просто строки и не могут быть выполнены).
Однако то, что вы можете сделать, - это написать запрос, который будет выполнять перекрестную ссылку на несколько значений, которые сами по себе являются динамическими ...