在if条件中计数

  • 本文关键字:条件 if xslt-1.0
  • 更新时间 :
  • 英文 :


我有一个xml文档,其中包括几个测试定义块。在使用xsl转换时,我想将这些具有相同名称的测试定义块合并在一起。在它们被合并之后,我想给每个合并的测试定义分配一个数字(顺序)。

输入例子:(顺序处处为0是故意的,因为我不知道在这一点上,合并后还会有多少测试)

<TestDef>
    <Name>Test1</Name>
    <Order>0</Order>
    <Results>
        <Result Name="Result1"/>
        <Result Name="Result2"/>
    </Results>
</TestDef>
<TestDef>
    <Name>Test2</Name>
    <Order>0</Order>
    <Results>
        <Result Name="Result5"/>
        <Result Name="Result6"/>
    </Results>
</TestDef>
<TestDef>
    <Name>Test1</Name>
    <Order>0</Order>
    <Results>
        <Result Name="Result3"/>
        <Result Name="Result4"/>
    </Results>
</TestDef>

想要输出:(现在每个合并的测试都分配了一个订单号,从1开始,没有间隔地计算)

<TestDef>
    <Name>Test1</Name>
    <Order>1</Order>
    <Results>
        <Result Name="Result1"/>
        <Result Name="Result2"/>
        <Result Name="Result3"/>
        <Result Name="Result4"/>
    </Results>
</TestDef>
<TestDef>
    <Name>Test2</Name>
    <Order>2</Order>
    <Results>
        <Result Name="Result5"/>
        <Result Name="Result6"/>
    </Results>
</TestDef>
当前输出:

(Test2的Order标签是重点)

<TestDef>
    <Name>Test1</Name>
    <Order>1</Order>
    <Results>
        <Result Name="Result1"/>
        <Result Name="Result2"/>
        <Result Name="Result3"/>
        <Result Name="Result4"/>
    </Results>
</TestDef>
<TestDef>
    <Name>Test2</Name>
    <Order>3</Order>
    <Results>
        <Result Name="Result5"/>
        <Result Name="Result6"/>
    </Results>
</TestDef>

我当前的xslt:

<xsl:key name="unique-tests" match="TestDef" use="Name" />
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>
<!-- Merge all tests with the same name together and add all results to
the one new test
This grouping was done, using the Muenchian Method: 
http://www.jenitennison.com/xslt/grouping/muenchian.html -->    
<xsl:template match="TestDef">
    <xsl:if test="generate-id()= generate-id(key('unique-tests', Name))">
        <Name>
            <xsl:value-of select="Name" />
        </Name>
        <Order>
            <xsl:number />
        </Order>
        <Results>
            <xsl:for-each select="key('unique-tests', Name)">
                <xsl:copy-of select="Results/node()"/>
            </xsl:for-each>
        </Results>
    </xsl:if>
</xsl:template>

问题:

分组工作得很好,但是订单号不能按我想要的方式工作。当我像在所示的xslt中那样使用<xsl:number/>时,他将从输入中计数每个测试,但只输出一些数字。我的示例的输出可能类似于Test1 (order = 1)和Test2 (order = 3)。

当我在if条件之前添加<xsl:number/>的额外输出时,他将按顺序输出每个数字,即使测试定义本身不会在输出中存在。

现在我看到了其他类似的问题:xsl counter with和condition在这里,它们与一个条件一起计数,但是由于我自己的条件不能用XPath表示,所以我不能将它用于<xsl:number/>

count属性

所以,我想让Order标签计数从1到我在输出中拥有的TestDefs的任何数量,没有任何间隙。我该怎么做呢?

依我之见,最好是选择性地应用模板-即仅对那些TestDef元素,首先在他们的组-然后使用position()函数对它们进行编号。

为了演示,我们必须首先有一个具有单个根元素的有效XML输入,例如: XML>
<root>
    <TestDef>
        <Name>Test1</Name>
        <Order>0</Order>
        <Results>
            <Result Name="Result1"/>
            <Result Name="Result2"/>
        </Results>
    </TestDef>
    <TestDef>
        <Name>Test2</Name>
        <Order>0</Order>
        <Results>
            <Result Name="Result5"/>
            <Result Name="Result6"/>
        </Results>
    </TestDef>
    <TestDef>
        <Name>Test1</Name>
        <Order>0</Order>
        <Results>
            <Result Name="Result3"/>
            <Result Name="Result4"/>
        </Results>
    </TestDef>
</root>

那么你可以这样做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="unique-tests" match="TestDef" use="Name" />
<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="/root">
    <xsl:copy>
        <xsl:apply-templates select="TestDef[generate-id() = generate-id(key('unique-tests', Name)[1])]"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="TestDef">
    <xsl:copy>
        <Name><xsl:value-of select="Name" /></Name>
        <Order><xsl:value-of select="position()" /></Order>
        <Results>
            <xsl:for-each select="key('unique-tests', Name)">
                <xsl:copy-of select="Results/node()"/>
            </xsl:for-each>
        </Results>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

或者,您也可以将您的条件复制到xsl:number,通过使用:

<xsl:number count="TestDef[generate-id() = generate-id(key('unique-tests', Name)[1])]"/>

相关内容

  • 没有找到相关文章

最新更新