XSLT有条件增量(xslt conditional increment)

2019-08-03 13:17发布

我有增加在一定条件下的反问题。

输入:

<Users>
  <User>
    <id>1</id>
    <username>jack</username>
  </User>
  <User>
    <id>2</id>
    <username>bob</username>
  </User>
  <User>
    <id>3</id>
    <username>bob</username>
  </User>
  <User>
    <id>4</id>
    <username>jack</username>
  </User>
</Users>

通缉输出:

<Users>
  <User>
    <id>1</id>
    <username>jack01</username>
  </User>
  <User>
    <id>2</id>
    <username>bob01</username>
  </User>
  <User>
    <id>3</id>
    <username>bob02</username>
  </User>
  <User>
    <id>4</id>
    <username>jack02</username>
  </User>
</Users>

要做到这一点下面的算法可用于:

  • 通过用户名输入排序
  • 为每个用户
    • 当原有的用户名是等于当前用户名
      • 增量计数器
      • 设置好用户名为“$用户名$计数器”
    • 除此以外
      • 计数器设置为1
  • (由ID排序再次 - 不是真的有必要)

于是,我就变成XSLT这样的:

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

  <xsl:template match="Users">
    <Users>
    <xsl:apply-templates select="create_user">
      <xsl:sort select="User/username"/>
    </xsl:apply-templates>
    </Users>
  </xsl:template>

  <xsl:template match="create_user">
    <id><xsl:value-of select="id"/></id>
    <xsl:choose>
      <xsl:when test="username=(preceding-sibling::User[1]//username)">
        <xsl:variable name="count">
          <xsl:number format="01"/>
        </xsl:variable>
        <username><xsl:value-of select="concat(username, $count)"/></username>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="count">
          <xsl:number value="1" format="01"/>
        </xsl:variable>
        <username><xsl:value-of select="concat(username, $count)"/></username>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>    

然而,通过执行这个,我得到以下错误:

  • 用户名不排序
  • 计数器不递增
    • 条件相匹配时,而不是计数器将是当前节点位置。
    • 对于我们的例子中ID为节点= 3将具有用户名= bob03
  • 缺少标记

有什么想法吗?

Answer 1:

这一转变

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

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

 <xsl:template match="username/text()">
  <xsl:value-of select="."/>
  <xsl:value-of select=
  "format-number(count(../../preceding-sibling::*[username=current()])+1,
                '00')
  "/>
 </xsl:template>
</xsl:stylesheet>

当施加在提供的XML文档:

<Users>
    <User>
        <id>1</id>
        <username>jack</username>
    </User>
    <User>
        <id>2</id>
        <username>bob</username>
    </User>
    <User>
        <id>3</id>
        <username>bob</username>
    </User>
    <User>
        <id>4</id>
        <username>jack</username>
    </User>
</Users>

产生想要的,正确的结果

<Users>
   <User>
      <id>1</id>
      <username>jack01</username>
   </User>
   <User>
      <id>2</id>
      <username>bob01</username>
   </User>
   <User>
      <id>3</id>
      <username>bob02</username>
   </User>
   <User>
      <id>4</id>
      <username>jack02</username>
   </User>
</Users>


Answer 2:

“递增计数器”是不是你在一个函数式编程语言做什么。 您需要描述你想要的输出作为输入的功能(如Dimitre做了),而不是描述用于计算输出过程或程序。



文章来源: xslt conditional increment