使用 xsl:number 元素时从 0 开始计数而不是 1 [英] Start count at zero instead of one when using xsl:number element

查看:22
本文介绍了使用 xsl:number 元素时从 0 开始计数而不是 1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我想我找到了

我相信这是您在 您的其他问题中要求的结果.

<小时>

请注意,match 不是 xsl:apply-templates 的有效属性.

EDIT:
I think I found a way around this issue while still using XSLT 1.0, although very verbose and probably prone to errors.


Is there a way to use the <xsl:number> element but start counting at zero instead of one, especially when using level="multiple"?

I'm using XSLT 1.0.

Current result: 1.2.2. Subitem_B
Expected result: 0.1.1. Subitem_B

I tried format="0" but it only outputs the points (i.e. ... Subitem_B)

<xsl:number level="multiple" format="0. "/>

Bonus question: I found a way around it using translate($number,'.','-'), but I'd still be curious to know if there is a way use a custom character instead of the points as delimiters, or even a custom format altogether.

XML Input

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl" version="1.0"?>
<root>
  <item>Main_A
    <item>Item_A</item>
    <item>Item_B
      <item>Subitem_A</item>
      <item>Subitem_B</item>
    </item>
    <item>Item_C</item>
  </item>
  <item>Main_B
    <item>Item_A
      <item>Subitem_A</item>
      </item>
    <item>Item_B</item>
  </item>
</root>

XSLT 1.0 Stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="root">
  <html>
    <body>
      <xsl:apply-templates match="item"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="item">
  <xsl:number level="multiple" format="1. "/>
  <xsl:apply-templates match="item"/>
</xsl:template>

</xsl:stylesheet>

HTML Output

<html>
  <body>
  1. Main_A
    1.1. Item_A
    1.2. Item_B
      1.2.1. Subitem_A
      1.2.2. Subitem_B

    1.3. Item_C

  2. Main_B
    2.1. Item_A
      2.1.1. Subitem_A

    2.2. Item_B

</body>
</html>

解决方案

If your processor supports the EXSLT str:tokenize() extension function (as I believe it does), you can do:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">

<xsl:template match="/root">
    <html>
        <body>
            <ul>
                <xsl:apply-templates select="item"/>
            </ul>
        </body>
    </html>
</xsl:template>

<xsl:template match="item">
    <xsl:variable name="num">
        <xsl:number level="multiple" format="1."/>
    </xsl:variable>
    <li>
        <xsl:text>path:</xsl:text>
        <xsl:for-each select="str:tokenize($num, '.')">         
            <xsl:value-of select=". - 1" />
            <xsl:if test="position()!=last()">
                <xsl:text>:</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text> = </xsl:text>
        <xsl:value-of select="text()" />
        <xsl:if test="item">
            <ul>
                <xsl:apply-templates select="item"/>
            </ul>
        </xsl:if>
    </li>
</xsl:template>

</xsl:stylesheet>

Applied to your input example, the result will be:

<html>
<body>
<ul>
<li>path:0 = Main_A
    <ul>
<li>path:0:0 = Item_A</li>
<li>path:0:1 = Item_B
      <ul>
<li>path:0:1:0 = Subitem_A</li>
<li>path:0:1:1 = Subitem_B</li>
</ul>
</li>
<li>path:0:2 = Item_C</li>
</ul>
</li>
<li>path:1 = Main_B
    <ul>
<li>path:1:0 = Item_A
      <ul>
<li>path:1:0:0 = Subitem_A</li>
</ul>
</li>
<li>path:1:1 = Item_B</li>
</ul>
</li>
</ul>
</body>
</html>

rendered as:

which I believe is the result you asked for in your other question.


Note that match is not a valid attribute of xsl:apply-templates.

这篇关于使用 xsl:number 元素时从 0 开始计数而不是 1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆