【问题标题】:Sequence number in xslt for Nested tags in a loopxslt中的序列号用于循环中的嵌套标签
【发布时间】:2015-08-23 11:05:04
【问题描述】:

我正在尝试在输出文本文件中为以下 xml 生成序列号以及一些标记数据。 输入 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 -从第二行构建一个版本 -下一行包含版本 -last Android 标记出现在末尾包含 2 个静态行。

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    我相信分两遍这样做会更方便:

    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
    

    【讨论】:

    • 感谢您的解决方案,我已将其应用于我的 xml,但输出文件为空。在我的实际 xsl 中,我使用调用模板(显示实际数据)并将其存储在变量(模板数据)中并在节点值属性中使用它。例如:。我可以这样用吗?
    • @Jarvis 我看不到你修改过的代码,所以我不能告诉你它有什么问题。我也不明白为什么有必要这样修改它。
    • 在我的实际 xml 中,我有多个标签要显示,所以我准备了模板来显示值。所以我正在调用模板并将值存储在节点>值属性中。如何将该变量存储在此节点中?
    • @Jarvis 恐怕我不明白你的意思。以上适用于您发布的示例(添加根元素后)。如果你不能让它与你的实际 XML 一起工作,那么要么编辑你的问题并向我们展示它的真实样子,要么发布一个新问题。
    • 感谢您,我设法为我的实际 xml 找到了解决方案。
    猜你喜欢
    • 2012-09-06
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    相关资源
    最近更新 更多