xsl 中的条件自动增量

发布于 2024-08-03 03:46:07 字数 1771 浏览 8 评论 0原文

我有一个像这样的 XML:

<V>
  <W>
    <X>1</X> 
  </W>
  <W>
    <Y>1</Y> 
  </W>
  <W>
    <X>1555</X> 
  </W>
  <W>
    <X>1</X> 
  </W>
</V>

我想让它像这样:

<entity ID="start">
    <f ID="NewField">0001</f>
    <f ID="NewField">0001</f>
    <f ID="NewField">0002</f>
    <f ID="NewField">0003</f>
</entity>

当字段为 V/W/X 时,NewField 应该增加 1,就像标签 V/W/X 的次数一样成立。 V/W/Y 也类似。

我正在使用的 XSL 是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<entity ID="start">
    <xsl:for-each select="V/W">
        <xsl:if test="X">
            <xsl:variable name="my_var">
                <xsl:value-of select="concat('000',position())"/>
            </xsl:variable>
            <f ID="NewField"><xsl:value-of  select="$my_var"/></f>
        </xsl:if>
        <xsl:if test="Y">
            <xsl:variable name="my_var">
                <xsl:value-of select="concat('000',position())"/>
            </xsl:variable>
            <f ID="NewField"><xsl:value-of  select="$my_var"/></f>
        </xsl:if>
    </xsl:for-each>
</entity>
</xsl:template>
</xsl:stylesheet>

,但它给了我一个错误的结果,如下所示:

<entity ID="start">
  <f ID="NewField">0001</f>
  <f ID="NewField">0002</f> 
  <f ID="NewField">0003</f> 
  <f ID="NewField">0004</f> 
</entity>

I have an XML like this:

<V>
  <W>
    <X>1</X> 
  </W>
  <W>
    <Y>1</Y> 
  </W>
  <W>
    <X>1555</X> 
  </W>
  <W>
    <X>1</X> 
  </W>
</V>

I want to make it something like this:

<entity ID="start">
    <f ID="NewField">0001</f>
    <f ID="NewField">0001</f>
    <f ID="NewField">0002</f>
    <f ID="NewField">0003</f>
</entity>

When the field is V/W/X then NewField should be incremented by 1 as many times the tag V/W/X is found.
Similarly for V/W/Y.

The XSL which I am using is

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<entity ID="start">
    <xsl:for-each select="V/W">
        <xsl:if test="X">
            <xsl:variable name="my_var">
                <xsl:value-of select="concat('000',position())"/>
            </xsl:variable>
            <f ID="NewField"><xsl:value-of  select="$my_var"/></f>
        </xsl:if>
        <xsl:if test="Y">
            <xsl:variable name="my_var">
                <xsl:value-of select="concat('000',position())"/>
            </xsl:variable>
            <f ID="NewField"><xsl:value-of  select="$my_var"/></f>
        </xsl:if>
    </xsl:for-each>
</entity>
</xsl:template>
</xsl:stylesheet>

but it gives me a wrong result, something like this:

<entity ID="start">
  <f ID="NewField">0001</f>
  <f ID="NewField">0002</f> 
  <f ID="NewField">0003</f> 
  <f ID="NewField">0004</f> 
</entity>

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

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

发布评论

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

评论(3

梦途 2024-08-10 03:46:07

如果您想使用 XSLT 对节点进行编号,那么 xsl:number 元素 可以提供帮助:

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

  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <entity ID="start">
      <xsl:apply-templates select="descendant::X | descendant::Y"/>
    </entity>
  </xsl:template>

  <xsl:template match="X | Y">
    <f ID="NewField"><xsl:number level="any" format="0000"/></f>
  </xsl:template>

</xsl:stylesheet>

If you want to number nodes with XSLT then the xsl:number element can help:

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

  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <entity ID="start">
      <xsl:apply-templates select="descendant::X | descendant::Y"/>
    </entity>
  </xsl:template>

  <xsl:template match="X | Y">
    <f ID="NewField"><xsl:number level="any" format="0000"/></f>
  </xsl:template>

</xsl:stylesheet>
木槿暧夏七纪年 2024-08-10 03:46:07

我认为您正在寻找类似 count(preceding::X) 表达式的内容。当然,您可能想让它变得更复杂,然后注意数字格式,但这听起来像是您正在寻找的起点。

I think you're looking for something like count(preceding::X) expression. Of course you may want to make it more complex and then take care about number formatting, but that sounds like a starting point you're looking for.

み格子的夏天 2024-08-10 03:46:07
<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="V">
    <entity ID="start">
      <xsl:apply-templates select="W/X|W/Y" />
    </entity>
  </xsl:template>

  <xsl:template match="X|Y">
    <f ID="NewField">
      <xsl:variable name="counter" select="
        count(
          parent::W/preceding-sibling::W/*[name() = name(current())]
        ) + 1
      " />
      <xsl:value-of select="format-number($counter, '0000')" />
    </f>
  </xsl:template>

</xsl:stylesheet>

这:

parent::W/preceding-sibling::W/*[name() = name(current())]

选择与当前元素同名的所有前面的元素。例如,如果执行点在此节点上:

<X>1555</X> 

它会向上一级 (parent::W),然后选择所有前面的 同级,并且它选择名称为 X 的任何子级 (*) - 因为 Xcurrent()< /代码> 元素。

对所得节点集进行计数并加一。 format-number() 用于生成漂亮干净的输出:

<entity ID="start">
  <f ID="NewField">0001</f>
  <f ID="NewField">0001</f>
  <f ID="NewField">0002</f>
  <f ID="NewField">0003</f>
</entity>
<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="V">
    <entity ID="start">
      <xsl:apply-templates select="W/X|W/Y" />
    </entity>
  </xsl:template>

  <xsl:template match="X|Y">
    <f ID="NewField">
      <xsl:variable name="counter" select="
        count(
          parent::W/preceding-sibling::W/*[name() = name(current())]
        ) + 1
      " />
      <xsl:value-of select="format-number($counter, '0000')" />
    </f>
  </xsl:template>

</xsl:stylesheet>

This:

parent::W/preceding-sibling::W/*[name() = name(current())]

selects all preceding elements of the same name as the current element. E.g., if the point of execution is on this node:

<X>1555</X> 

It goes one level up (parent::W), then selects all preceding <W> siblings, and of those it selects any child (*) that has a name of X - since X is the name of the current() element.

The resulting node-set is counted and incremented by one. format-number() is used to generate a nice clean output:

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