Я пытался использовать вышеуказанную функцию, но выдает ошибку:
XPDY0002: Cannot select a node here: the context item is undefined
Но когда я попробовал это в названном шаблоне, я смог получить
результат.
Согласно спецификации W3C XSLT 2.0:
" В теле функции таблицы стилей фокус изначально
не определено; это означает, что любая попытка сослаться на элемент контекста,
позиция контекста или размер контекста является невосстановимой динамической ошибкой .
[XPDY0002] "
В вашем коде:
<xsl:function name="fn:generateXPath" >
<xsl:for-each select="ancestor::*">
<xsl:value-of select="name()" />
</xsl:for-each>
<xsl:value-of select="name()" />
</xsl:function>
существует ряд относительных выражений, которые могут быть оценены только относительно элемента контекста (фокус, текущий узел), однако такого определения не существует по определению (см. Цитату выше), и таким образом вы получаете сообщенная ошибка.
Решение
Добавьте параметр для этой функции - естественно, что это будет узел, XPath для выбора которого требуется:
<xsl:function name="fn:generateXPath" as="xs:string" >
<xsl:param name="pNode" as="node()"/>
<xsl:for-each select="$pNode/ancestor::*">
<xsl:value-of select="name()" />
</xsl:for-each>
<xsl:value-of select="name($pNode)" />
</xsl:function>
и вызвать эту функцию следующим образом:
fn:generateXPath(someNode)
Примечание : Очевидно, вам необходимо объединить каждое имя в символ "/"
, а также сузить выражение, чтобы не выбирать какие-либо узлы узла, используя позиции в предикатах. Полное и правильное решение, которое создает выражение XPath для узла, см. В моем ответе на этот вопрос: https://stackoverflow.com/a/4747858/36305