3

出于调试目的,从模板中输出上下文节点的完整路径会很方便,是否有未缩写的 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 

或类似的东西。

4

2 回答 2

2

此转换为所需节点生成 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
于 2011-04-18T13:20:34.787 回答
1

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

<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, '&#xA;')" />
        <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(),  '&#xA;')" />
    </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
于 2011-04-18T15:45:56.030 回答