循环中嵌套标记的xslt中的序列号

时间:2015-08-23 11:05:04

标签: xml xslt xslt-2.0

我试图在输出文本文件中生成xml以下的序列号以及一些标记数据。 INPUT XML:

<OS>
     <Android>
        <codeName>Kitkat</codeName>
        <version>
           <build>123</build>
           <build>456</build>
           <build>789</build>
        </version>
        <version>
           <build>321</build>
        </version>
     </Android>
     <Android>
        <codeName>lollipop</codeName>
        <version>
           <build>654</build>
        </version>
     </Android>
</OS>
<OS>
     <Android>
        <codeName>Jelly bean</codeName>
     </Android>
     <Android>
        <codeName>Marshmallow</codeName>
        <version>
           <build>879</build>
        </version>
        <version>
           <build>312</build>
           <build>645</build>
        </version>
     </Android>
</OS>

预期产出:

kitkat      1 000
build       2 123
build       3 456
build       4 789
version     5 000
build       6 321
version     7 000
lollipop    8 000
build       9 654
version    10 000
static1    11 000
static2    12 000
Jelly bean 13 000
Marshmallow14 000
build      15 879
version    16 000
build      17 312
build      18 645
version    19 000
static1    20 000
static2    21 000

到目前为止我尝试了什么:

<xsl:template match="OS/Android">
   <xsl:variable name="pos" select="position()+(2*count(preceding::OS))+2*count(preceding::Android/version)+2*count(preceding::Android/version/build)"/>
   <xsl:value-of select="codeName"/>
   <xsl:value-of select="$pos"/>
   <xsl:text>000</xsl:text>
   <xsl:text>&#xa</xsl:text>
   <xsl:for-each select="version">
      <xsl:for-each select="build">
         <xsl:text>build</xsl:text>
         <xsl:value-of select="$pos"/>
         <xsl:value-of select="build"/>
         <xsl:text>&#xa</xsl:text>
      </xsl:for-each>
         <xsl:text>version</xsl:text>
         <xsl:value-of select="$pos"/>
         <xsl:text>000</xsl:text>
         <xsl:text>&#xa</xsl:text>
   </xsl:for-each>
</xsl:template>
<xsl:template match="OS/Android[last()]">
   <xsl:variable name="pos" select="position()+(2*count(preceding::OS))+2*count(preceding::Android/version)+2*count(preceding::Android/version/build)"/>
   <xsl:value-of select="codeName"/>
   <xsl:value-of select="$pos"/>
   <xsl:text>000</xsl:text>
   <xsl:text>&#xa</xsl:text>
   <xsl:for-each select="version">
      <xsl:for-each select="build">
         <xsl:text>build</xsl:text>
         <xsl:value-of select="$pos"/>
         <xsl:value-of select="build"/>
         <xsl:text>&#xa</xsl:text>
      </xsl:for-each>
         <xsl:text>version</xsl:text>
         <xsl:value-of select="$pos"/>
         <xsl:text>000</xsl:text>
         <xsl:text>&#xa</xsl:text>
   </xsl:for-each>
   <xsl:text>static1</xsl:text>
   <xsl:value-of select="$pos"/>
   <xsl:text>000</xsl:text>
   <xsl:text>&#xa</xsl:text>
   <xsl:text>static2</xsl:text>
   <xsl:value-of select="$pos"/>
   <xsl:text>000</xsl:text>
   <xsl:text>&#xa</xsl:text>

</xsl:template>

问题是我无法在输出中生成正确的序列号(pos)。请帮助我实现这个逻辑。

注意事项: - 第一行始终包含codeName -from第二行构建版本 -next行包含版本 -last Android标记出现最后包含2条静态行。

1 个答案:

答案 0 :(得分:3)

我相信两次通过会更方便:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>

<xsl:template match="/root">
    <!-- first pass -->
    <xsl:variable name="nodes">
        <xsl:apply-templates select="OS"/>
    </xsl:variable>
    <!-- output -->
    <xsl:for-each select="$nodes/node">
        <xsl:value-of select="@name"/>
        <xsl:text>&#9;</xsl:text>
        <xsl:value-of select="position()"/>
        <xsl:text>&#9;</xsl:text>
        <xsl:value-of select="@value"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

<!-- first pass templates: -->

<xsl:template match="OS">
    <xsl:apply-templates select="Android"/>
    <node name="static1" value="000"/>
    <node name="static1" value="000"/>
</xsl:template>

<xsl:template match="Android">
    <node name="{codeName}" value="000"/>
    <xsl:apply-templates select="version"/>
</xsl:template>

<xsl:template match="version">
    <xsl:apply-templates select="build"/>
    <node name="version" value="000"/>
</xsl:template>

<xsl:template match="build">
    <node name="build" value="{.}"/>
</xsl:template>

</xsl:stylesheet>

当应用于格式正确的输入时(即在您的示例中添加根元素之后),结果将为:

Kitkat  1   000
build   2   123
build   3   456
build   4   789
version 5   000
build   6   321
version 7   000
lollipop    8   000
build   9   654
version 10  000
static1 11  000
static1 12  000
Jelly bean  13  000
Marshmallow 14  000
build   15  879
version 16  000
build   17  312
build   18  645
version 19  000
static1 20  000
static1 21  000