具有不同输出的XSL序列分配

时间:2013-12-24 06:26:33

标签: xml xslt xslt-1.0

在一个简化的 - 高度捏造的例子中,假设我有一个源文档,其中有一堆不同的节点,如:

<Root>
    <Parent> <!-- potential repeater -->
        <Pelican>
            <NumberOfLegs>2</NumberOfLegs>
        </Pelican>
        <PoorlyBuiltTable>
            <NumberOfLegs>3</NumberOfLegs>
        </PoorlyBuiltTable>
        <Box />
    </Parent>
</Root>

我需要输出XML,如:

<Root>
    <Parent>
        <Thing id="1" Seq="1" />
        <Thing id="1" Seq="2" />
        <Thing id="2" Seq="3" />
        <Thing id="2" Seq="4" />
        <Thing id="2" Seq="5" />
        <Thing id="3" Seq="6" />
    </Parent>
</Root>

这样我就需要生成id以匹配来自源的不同节点以及Seq在{{1}范围内分配给Thing (即Parentid可以重复,如果Seq有一个有类似孩子的兄弟姐妹。)

使用带有递归循环Parent的一个样式表来生成所有template实例然后使用{{生成第二个 - 后续 - 样式表,是否有一个更好的解决方案1}}生成我的所有Thing属性?

1 个答案:

答案 0 :(得分:0)

为了理智,让我按如下方式重写你的意见:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <parent id="1">
        <plural>
            <quantity>2</quantity>
        </plural>
        <plural>
            <quantity>3</quantity>
        </plural>
        <singular/>
        <singular/>
        <plural>
            <quantity>2</quantity>
        </plural>
        <singular/>
    </parent>
    <parent id="2">
        <plural>
            <quantity>3</quantity>
        </plural>
        <singular/>
        <plural>
            <quantity>2</quantity>
        </plural>
        <singular/>
    </parent>
</root>

现在,应用以下样式表:

<?xml version="1.0" encoding="UTF-8"?>
<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:template match="/root">
<result>
    <xsl:for-each select="parent">
    <group parent="{@id}">
        <xsl:for-each select="*">
        <xsl:call-template name="gen">
            <xsl:with-param name="id" select="position()"/>
            <xsl:with-param name="start" 
                            select="sum(preceding-sibling::*[quantity>0]/quantity)
                                  + count(preceding-sibling::*[not(quantity>0)])"/>
            <xsl:with-param name="n">
                <xsl:choose>
                    <xsl:when test="quantity>0">
                        <xsl:value-of select="quantity" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="1" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:with-param>
        </xsl:call-template>
        </xsl:for-each>
    </group>
    </xsl:for-each>
</result>
</xsl:template>

<xsl:template name="gen">
    <xsl:param name="id"/>
    <xsl:param name="start"/>
    <xsl:param name="n"/>
    <xsl:param name="i" select="1"/>
<xsl:choose>
    <xsl:when test="$i > $n"/>
    <xsl:otherwise>
        <item id="{$id}" Seq="{$start+$i}" />
        <xsl:call-template name="gen">
            <xsl:with-param name="id" select="$id"/>
            <xsl:with-param name="start" select="$start"/>
            <xsl:with-param name="n" select="$n"/>
            <xsl:with-param name="i" select="$i+1"/>
        </xsl:call-template>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

将产生以下结果:

<?xml version="1.0" encoding="utf-8"?>
<result>
  <group parent="1">
    <item id="1" Seq="1"/>
    <item id="1" Seq="2"/>
    <item id="2" Seq="3"/>
    <item id="2" Seq="4"/>
    <item id="2" Seq="5"/>
    <item id="3" Seq="6"/>
    <item id="4" Seq="7"/>
    <item id="5" Seq="8"/>
    <item id="5" Seq="9"/>
    <item id="6" Seq="10"/>
  </group>
  <group parent="2">
    <item id="1" Seq="1"/>
    <item id="1" Seq="2"/>
    <item id="1" Seq="3"/>
    <item id="2" Seq="4"/>
    <item id="3" Seq="5"/>
    <item id="3" Seq="6"/>
    <item id="4" Seq="7"/>
  </group>
</result>