首页 > 解决方案 > 旁边有相同元素的 xsl 编号

问题描述

我需要用以下结构格式化一些xml数据

<list>
  <item>
    Test
  </item>
  <item>
    Testt
  </item>
  <or-item>
    TestOr
  </or-item>
  <or-item>
    TestOrr
  </or-item>
  <item>
    Testtt
  </item>
  <or-item>
    TestOrrr
  </or-item>
  <item>
    Testttt
  </item>
</list>

必须使用该位置的第二级计数格式化xsl:number。我知道内部or-item结构会更好,但数据是这样给出的。or-itemitem

我需要一种方法来计算or-item当前的下一个or-item来计算编号xsl:number

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.1"
xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions" xmlns:fn="http://www.w3.org/2005/xpath-functions">

  <xsl:output encoding="UTF-8" method="html" indent="yes"/>

  <xsl:template match="list">
    <div>
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="item">
    <div>
      <xsl:number count="item"/>
      <xsl:value-of select="."/>
    </div>
  </xsl:template>

  <xsl:template match="or-item">
    <div style="padding-left: 10px">
      <xsl:number value="count(//or-item)" format="a) "/>
      <xsl:value-of select="."/>
    </div>
  </xsl:template>

</xsl:stylesheet>

编辑

我在 linux 上使用 XSLT 1.1 和 xsltproc,但如果需要的话 2.0 是可能的

在此处输入图像描述

标签: xsltxpath

解决方案


由于目标格式是 HTML,您似乎可以依靠使用xsl:for-each-groupand创建适当的嵌套 HTML 有序列表group-starting-with="item"

  <xsl:template match="list">
      <ol>
          <xsl:for-each-group select="*" group-starting-with="item">
              <li>
                  <xsl:value-of select="."/>
                  <xsl:where-populated>
                      <ol>
                          <xsl:apply-templates select="tail(current-group())"/>
                      </ol>
                  </xsl:where-populated>
              </li>
          </xsl:for-each-group>
      </ol>
  </xsl:template>

  <xsl:template match="or-item">
      <li>
          <xsl:value-of select="."/>
      </li>
  </xsl:template>

https://xsltfiddle.liberty-development.net/ejivJrM

该示例使用了一些 XSLT/XPath 3 之类的东西were-populatedtail但如果需要 XSLT 2 兼容性,则可以将其替换为<xsl:if test="subsequence(current-group(), 2)"><ol><xsl:apply-templates select="subsequence(current-group(), 2)"/></xsl:if>.

当然,没有必要使用 HTML 有序列表,如果需要/想要,您可以使用使用的分组方法将输入转换为嵌套 div,然后在第二步format-number中按照您的意愿使用:

  <xsl:template match="list">
      <xsl:variable name="nested-list">
          <xsl:for-each-group select="*" group-starting-with="item">
              <xsl:copy>
                  <xsl:value-of select="."/>
                  <xsl:copy-of select="tail(current-group())"/>
              </xsl:copy>
          </xsl:for-each-group>              
      </xsl:variable>
      <div>
        <xsl:apply-templates select="$nested-list"/>
      </div>
  </xsl:template>

  <xsl:template match="item">
    <div>
      <xsl:number/>
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="or-item">
    <div style="padding-left: 10px">
      <xsl:number format="a) "/>
      <xsl:value-of select="."/>
    </div>
  </xsl:template>

https://xsltfiddle.liberty-development.net/ejivJrM/1


推荐阅读