XSL迭代属性并忽略某些元素



我需要做一件相当简单的事情,即迭代XML中的元素(XML下的更多解释)

<form>
<field index="1" name="field_X_1" group="firstGroup" type="String">
<value>Value of Field X 1 of first group</value>
</field>
<field index="1" name="field_Y_1" group="firstGroup" type="String">
<value>Value of Field Y 1 of first group</value>
</field>
<field index="2" name="field_X_2" group="firstGroup" type="String">
<value>Value of Field X 2 of first group</value>
</field>
<field index="2" name="field_Y_2" group="firstGroup" type="String">
<value>Value of Field Y 2 of first group</value>
</field>
<field index="1" name="field_A_1" group="secondGroup" type="String">
<value>Value of Field A 1 of second group</value>
</field>
<field index="1" name="field_B_1" group="secondGroup" type="String">
<value>Value of Field B 1 of second group</value>
</field>
<field index="2" name="field_A_2" group="secondGroup" type="String">
<value>Value of Field A 2 of second group</value>
</field>
<field index="2" name="field_B_2" group="secondGroup" type="String">
<value>Value of Field B 2 of second group</value>
</field>

</form>

现在我正在迭代firstGroup的所有字段,每次我发现索引发生了变化(通过比较索引和sibbling的索引),我都会添加新行字符)。问题是,我只需要对索引进行迭代(但仍然保持firstGroup和secondGroup之间的距离)。

我的输出应该看起来像

Value of Field X 1 of first group, Value of Field Y 1 of first group
Value of Field X 2 of first group, Value of Field Y 2 of first group
Value of Field A 1 of second group, Value of Field B 1 of second group
Value of Field A 2 of second group, Value of Field B 2 of second group
etc

我的XSL现在看起来像

    <xsl:for-each select='/form/field[@group="firstGroup"]'>
                <xsl:sort select="@index" order="ascending"></xsl:sort>     
                <xsl:if test='preceding-sibling::*[@group="firstGroup"][1]/@index != @index and count(preceding-sibling::*) != 0 '>
                    <xsl:text>&#xa;</xsl:text>
                </xsl:if>
                <xsl:value-of select="//field[@name=concat('field_X_', @index,')]/value"/>                              
                <xsl:value-of select="//field[@name=concat('field_Y_', @index,')]/value"/>                              
     </xsl:for-each>    
<!-- Differente iteration for second group-->
<xsl:text>&#xa;</xsl:text>
<xsl:for-each select='/form/field[@group="firstGroup"]'>
                <xsl:sort select="@index" order="ascending"></xsl:sort>     
                <xsl:if test='preceding-sibling::*[@group="firstGroup"][1]/@index != @index and count(preceding-sibling::*) != 0 '>
                    <xsl:text>&#xa;</xsl:text>
                </xsl:if>
                <xsl:value-of select="//field[@name=concat('field_A_', @index,')]/value"/>                              
                <xsl:value-of select="//field[@name=concat('field_B_', @index,')]/value"/>                              
     </xsl:for-each>    

<xsl:output method="text" />
<xsl:template match="form">
    <!--* find all the groups *-->
    <xsl:variable name="groups">
        <xsl:call-template name="get-group-names">
            <xsl:with-param name="nodes" select="field" />
        </xsl:call-template>
    </xsl:variable>
    <xsl:call-template name="process-all-groups">
        <xsl:with-param name="group-names" select="$groups" />
    </xsl:call-template>
</xsl:template>
<xsl:template name="get-group-names">
    <xsl:param name="nodes" />
    <xsl:param name="result-so-far" />
    <xsl:choose>
        <xsl:when test="not($nodes)">
            <xsl:value-of select="$result-so-far" />
        </xsl:when>
        <xsl:when test="contains(
            concat(' ', $result-so-far),
            concat(' ', $nodes[1]/@group, ' '))" >
            <xsl:call-template name="get-group-names">
                <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]" />
                <xsl:with-param name="result-so-far" select="$result-so-far" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="get-group-names">
                <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]" />
                <xsl:with-param name="result-so-far"
                    select="concat($result-so-far, $nodes[1]/@group, ' ')" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
<xsl:template name="process-all-groups">
    <xsl:param name="group-names" />
    <xsl:variable name="group" select="substring-before($group-names, ' ')"/>
    <xsl:if test="not(string-length($group) = 0)">
        <xsl:call-template name="index">
            <xsl:with-param name="n" select="1" />
            <xsl:with-param name="group" select="$group" />
        </xsl:call-template>
        <xsl:call-template name="process-all-groups">
            <xsl:with-param name="group-names"
                select="substring-after($group-names, ' ')" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>
<xsl:template name="index">
    <xsl:param name="n" select="1" />
    <xsl:param name="group" />
    <xsl:variable name="with-n"
        select="/form/field[@group = $group][@index = $n]" />
    <xsl:if test="$with-n">
        <xsl:for-each select="$with-n">
            <xsl:sort use="@index" order="ascending" />
            <xsl:value-of select="value" />
            <xsl:if test="not(position() = last())">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#xa;</xsl:text>
        <xsl:call-template name="index">
            <xsl:with-param name="n" select="$n + 1" />
            <xsl:with-param name="group" select="$group" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>
<xsl:template match="field"></xsl:template>

最新更新