XSLT 1.0 中的输出上下文节点(完整路径)?

发布于 2024-11-01 14:54:05 字数 513 浏览 7 评论 0原文

出于调试目的,从模板内输出上下文节点的完整路径会很方便,是否有未缩写的 xpath 或函数来报告此情况?

示例模板:

<xsl:template match="@first">
        <tr>
            <td>
                <xsl:value-of select="??WHAT TO PUT IN HERE??"/>
            </td>
        </tr>
</xsl:template>

示例(节略)输入文档:

<people>
<person>
<name first="alan">
...

模板的输出类似于:

people / person / name / @first 

或类似的内容。

For debugging purposes it would be handy to output the full path of the context node from within a template, is there unabbreviated xpath or function to report this ?

Example Template:

<xsl:template match="@first">
        <tr>
            <td>
                <xsl:value-of select="??WHAT TO PUT IN HERE??"/>
            </td>
        </tr>
</xsl:template>

Example (Abridged) input document:

<people>
<person>
<name first="alan">
...

The output from the template would be something like:

people / person / name / @first 

Or something similar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沙与沫 2024-11-08 14:54:05

此转换为所需节点生成 XPath 表达式

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:variable name="vNode" select=
        "/*/*[2]/*/@first"/>
        <xsl:apply-templates select="$vNode" mode="path"/>
    </xsl:template>

    <xsl:template match="*" mode="path">
        <xsl:value-of select="concat('/',name())"/>
        <xsl:variable name="vnumPrecSiblings" select=
        "count(preceding-sibling::*[name()=name(current())])"/>
        <xsl:variable name="vnumFollSiblings" select=
        "count(following-sibling::*[name()=name(current())])"/>
        <xsl:if test="$vnumPrecSiblings or $vnumFollSiblings">
            <xsl:value-of select=
            "concat('[', $vnumPrecSiblings +1, ']')"/>
        </xsl:if>
    </xsl:template>

    <xsl:template match="@*" mode="path">
     <xsl:apply-templates select="ancestor::*" mode="path"/>
     <xsl:value-of select="concat('/@', name())"/>
    </xsl:template>
</xsl:stylesheet>

应用于以下 XML 文档时

<people>
 <person>
  <name first="betty" last="jones"/>
 </person>
 <person>
  <name first="alan" last="smith"/>
 </person>
</people>

生成所需的正确结果

/people/person[2]/name/@first

This transformation produces an XPath expression for the wanted node:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:variable name="vNode" select=
        "/*/*[2]/*/@first"/>
        <xsl:apply-templates select="$vNode" mode="path"/>
    </xsl:template>

    <xsl:template match="*" mode="path">
        <xsl:value-of select="concat('/',name())"/>
        <xsl:variable name="vnumPrecSiblings" select=
        "count(preceding-sibling::*[name()=name(current())])"/>
        <xsl:variable name="vnumFollSiblings" select=
        "count(following-sibling::*[name()=name(current())])"/>
        <xsl:if test="$vnumPrecSiblings or $vnumFollSiblings">
            <xsl:value-of select=
            "concat('[', $vnumPrecSiblings +1, ']')"/>
        </xsl:if>
    </xsl:template>

    <xsl:template match="@*" mode="path">
     <xsl:apply-templates select="ancestor::*" mode="path"/>
     <xsl:value-of select="concat('/@', name())"/>
    </xsl:template>
</xsl:stylesheet>

when applied on the following XML document:

<people>
 <person>
  <name first="betty" last="jones"/>
 </person>
 <person>
  <name first="alan" last="smith"/>
 </person>
</people>

the wanted, correct result is produced:

/people/person[2]/name/@first
溺孤伤于心 2024-11-08 14:54:05

这是一个样式表(具有可疑值),它打印文档中每个元素和属性的路径:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:strip-space elements="*" />
    <xsl:template match="*">
        <xsl:param name="pathToHere" select="''" />
        <xsl:variable name="precSiblings"
            select="count(preceding-sibling::*[name()=name(current())])" />
        <xsl:variable name="follSiblings"
            select="count(following-sibling::*[name()=name(current())])" />
        <xsl:variable name="fullPath"
            select="concat($pathToHere, '/', name(),
                substring(concat('[', $precSiblings + 1, ']'), 
                    1 div ($follSiblings or $precSiblings)))" />
        <xsl:value-of select="concat($fullPath, '
')" />
        <xsl:apply-templates select="@*|*">
            <xsl:with-param name="pathToHere" select="$fullPath" />
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:param name="pathToHere" select="''" />
        <xsl:value-of select="concat($pathToHere, '/@', name(),  '
')" />
    </xsl:template>
</xsl:stylesheet>

当应用于此输入时:

<people>
    <person>
        <name first="betty" last="jones" />
    </person>
    <person>
        <name first="alan" last="smith" />
    </person>
    <singleElement />
</people>

产生:

/people
/people/person[1]
/people/person[1]/name
/people/person[1]/name/@first
/people/person[1]/name/@last
/people/person[2]
/people/person[2]/name
/people/person[2]/name/@first
/people/person[2]/name/@last
/people/singleElement

Here's a stylesheet (of dubious value) that prints the path to every element and attribute in a document:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:strip-space elements="*" />
    <xsl:template match="*">
        <xsl:param name="pathToHere" select="''" />
        <xsl:variable name="precSiblings"
            select="count(preceding-sibling::*[name()=name(current())])" />
        <xsl:variable name="follSiblings"
            select="count(following-sibling::*[name()=name(current())])" />
        <xsl:variable name="fullPath"
            select="concat($pathToHere, '/', name(),
                substring(concat('[', $precSiblings + 1, ']'), 
                    1 div ($follSiblings or $precSiblings)))" />
        <xsl:value-of select="concat($fullPath, '
')" />
        <xsl:apply-templates select="@*|*">
            <xsl:with-param name="pathToHere" select="$fullPath" />
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:param name="pathToHere" select="''" />
        <xsl:value-of select="concat($pathToHere, '/@', name(),  '
')" />
    </xsl:template>
</xsl:stylesheet>

When applied to this input:

<people>
    <person>
        <name first="betty" last="jones" />
    </person>
    <person>
        <name first="alan" last="smith" />
    </person>
    <singleElement />
</people>

Produces:

/people
/people/person[1]
/people/person[1]/name
/people/person[1]/name/@first
/people/person[1]/name/@last
/people/person[2]
/people/person[2]/name
/people/person[2]/name/@first
/people/person[2]/name/@last
/people/singleElement
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文