模仿 XSLT 1.0 中的位置(节点集)?

发布于 2025-01-07 21:12:50 字数 841 浏览 1 评论 0原文

XSLT 2.0 的优点是可以将节点集参数作为position() 函数的一部分进行传递。不幸的是,这在 XSLT 1.0 中不可用。有没有办法模仿这种行为?

例如,给定此 XML:

<wishlists>
  <wishlist name="Games">
    <product name="Crash Bandicoot"/>
    <product name="Super Mario Brothers"/>
    <product name="Sonic the Hedgehog"/>
  </wishlist>
  <wishlist name="Movies">
    <product name="Back to the Future"/>
  </wishlist>
</wishlists>

和此 XSLT 2.0:

<xsl:value-of select="position(/wishlists/wishlist/product)"/>

在处理最终的“回到未来”节点时,将返回值“4”。

不幸的是,我似乎能够使用 XSLT 1.0 获得的最接近值如下:

<xsl:template match="product">
  <xsl:value-of select="position()"/>
</xsl:template>

但是,我会在同一个“回到未来”节点中获得值“1”,而不是我在“回到未来”节点中获得的值“4”。真的想要。

XSLT 2.0 offers the benefit of passing a node-set param as part of the position() function. Unfortunately, that is not available in XSLT 1.0. Is there a way to mimic this behavior?

For example, given this XML:

<wishlists>
  <wishlist name="Games">
    <product name="Crash Bandicoot"/>
    <product name="Super Mario Brothers"/>
    <product name="Sonic the Hedgehog"/>
  </wishlist>
  <wishlist name="Movies">
    <product name="Back to the Future"/>
  </wishlist>
</wishlists>

and this XSLT 2.0:

<xsl:value-of select="position(/wishlists/wishlist/product)"/>

the value "4" would be returned when processing the final "Back to the Future" node.

Unfortunately, the closest I seem to be able to get with XSLT 1.0 is the following:

<xsl:template match="product">
  <xsl:value-of select="position()"/>
</xsl:template>

However, I would get a value of "1" in the same "Back to the Future" node, as opposed to the "4" value that I really want.

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

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

发布评论

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

评论(2

太阳男子 2025-01-14 21:12:50

您可以使用前轴

此 XSLT 1.0 样式表:

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

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="product">
    <product position="{count(preceding::product) + 1}">
      <xsl:apply-templates select="@*"/>
    </product>    
  </xsl:template>

</xsl:stylesheet>

应用于您的 XML 输入会生成:

<wishlists>
   <wishlist name="Games">
      <product position="1" name="Crash Bandicoot"/>
      <product position="2" name="Super Mario Brothers"/>
      <product position="3" name="Sonic the Hedgehog"/>
   </wishlist>
   <wishlist name="Movies">
      <product position="4" name="Back to the Future"/>
   </wishlist>
</wishlists>

You can use the preceding axis.

This XSLT 1.0 stylesheet:

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

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="product">
    <product position="{count(preceding::product) + 1}">
      <xsl:apply-templates select="@*"/>
    </product>    
  </xsl:template>

</xsl:stylesheet>

Applied to your XML input produces:

<wishlists>
   <wishlist name="Games">
      <product position="1" name="Crash Bandicoot"/>
      <product position="2" name="Super Mario Brothers"/>
      <product position="3" name="Sonic the Hedgehog"/>
   </wishlist>
   <wishlist name="Movies">
      <product position="4" name="Back to the Future"/>
   </wishlist>
</wishlists>
咋地 2025-01-14 21:12:50

XSLT 2.0 的优点是可以将节点集参数作为
位置()函数。

这种说法是错误的。 position() 函数没有参数——无论是在 XPath 1.0 中还是在 XSLT 2.0 使用的 XPath 2.0 中。

您想要的是

count(preceding::product) +1

或者,也可以使用xsl:number指令。

以下是这两种方法的演示

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

 <xsl:variable name="vLastProd" select=
  "//product[@name='Back to the Future']"/>

 <xsl:template match="/">
     <xsl:value-of select="count($vLastProd/preceding::product) +1"/>
=========
<xsl:text/>
   <xsl:apply-templates select="$vLastProd"/>
 </xsl:template>

 <xsl:template match="product">
   <xsl:number level="any" count="product"/>    
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时

<wishlists>
    <wishlist name="Games">
        <product name="Crash Bandicoot"/>
        <product name="Super Mario Brothers"/>
        <product name="Sonic the Hedgehog"/>
    </wishlist>
    <wishlist name="Movies">
        <product name="Back to the Future"/>
    </wishlist>
</wishlists>

使用这两种方法都可以获得所需的正确结果 -- 并且输出

4
=========
4

注意:如果不直接输出,则需要将xsl:number的结果捕获到变量体内。

XSLT 2.0 offers the benefit of passing a node-set param as part of the
position() function.

This statement is wrong. The position() function has no arguments -- either in XPath 1.0 or in XPath 2.0, which XSLT 2.0 uses.

What you want is:

count(preceding::product) +1

or, alternatively, the xsl:number instruction can be used.

Here is a demonstration of both these methods:

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

 <xsl:variable name="vLastProd" select=
  "//product[@name='Back to the Future']"/>

 <xsl:template match="/">
     <xsl:value-of select="count($vLastProd/preceding::product) +1"/>
=========
<xsl:text/>
   <xsl:apply-templates select="$vLastProd"/>
 </xsl:template>

 <xsl:template match="product">
   <xsl:number level="any" count="product"/>    
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<wishlists>
    <wishlist name="Games">
        <product name="Crash Bandicoot"/>
        <product name="Super Mario Brothers"/>
        <product name="Sonic the Hedgehog"/>
    </wishlist>
    <wishlist name="Movies">
        <product name="Back to the Future"/>
    </wishlist>
</wishlists>

the wanted, correct result is obtained using both methods -- and output:

4
=========
4

Note: The result of xsl:number needs to be captured inside the body of a variable, if it will not be output directly.

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