基于子节点索引的XSLT映射

时间:2016-07-05 17:20:18

标签: xml xslt

XSLT新手。我有一个看起来像的< -

    <?xml version="1.0" encoding="UTF-8"?>
    <Parent>
        <Child1>
            <A>ContentAC1</A>
            <B>ContentBC1</B>
            <C>ContentCC1</C>
        </Child1>
        <Child2>
            <A>ContentAC2</A>
            <B>ContentBC2</B>
            <C>ContentCC2</C>
        </Child2>
        <Child3>
            <A>ContentAC3</A>
            <B>ContentBC3</B>
            <C>ContentCC3</C>
        </Child3>
        <Child4>
            <A>ContentAC4</A>
            <B>ContentBC4</B>
            <C>ContentCC4</C>
        </Child4>
        ...
   </Parent>

我想根据条件创建一个XSLT映射。如果子节点的数量&lt; = 3,我希望映射的xml看起来像 -

    <Children>
        <C1A>ContentAC1</C1A>
        <C1B>ContentBC1</C1B>
        <C1C>ContentCC1</C1C>
        <C2A>ContentAC2</C2A>
        <C2B>ContentBC2</C2B>
        <C2C>ContentCC2</C2C>
        <C3A>ContentAC3</C3A>
        <C3B>ContentBC3</C3B>
        <C3C>ContentCC3</C3C>
    </Children>

如果子节点数> 3,child3之后的每个孩子都应该映射到C3A,C3B和C3C。例如:如果子节点= 5,映射的xml应该看起来像 -

        <Children>
        <C1A>ContentAC1</C1A>
        <C1B>ContentBC1</C1B>
        <C1C>ContentCC1</C1C>

        <C2A>ContentAC2</C2A>
        <C2B>ContentBC2</C2B>
        <C2C>ContentCC2</C2C>

        <C3A>ContentAC3</C3A>
        <C3B>ContentBC3</C3B>
        <C3C>ContentCC3</C3C>

        <C3A>ContentAC3</C3A>
        <C3B>ContentBC3</C3B>
        <C3C>ContentCC3</C3C>

        <C3A>ContentAC3</C3A>
        <C3B>ContentBC3</C3B>
        <C3C>ContentCC3</C3C>
        </Children>

如何使用XSLT实现此目的?

1 个答案:

答案 0 :(得分:0)

重命名孙子很容易,但我认为如果可能的话,你会发现控制输出的空白区并不是那么简单。

在我尝试过的所有处理器中,Saxon 6.5.5 was the only one to produce the separators

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:template match="/Parent">
    <xsl:variable name="count-children" select="count(*)" />
    <Children>
        <xsl:for-each select="*">
            <xsl:variable name="i" select="position()"/>
            <xsl:for-each select="A | B | C">
                <xsl:element name="{concat('C', $i, name())}">
                    <xsl:value-of select="."/>
                </xsl:element>
            </xsl:for-each>
            <xsl:if test="$count-children > 3 and $i!=last()">
                <xsl:text>&#10;</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </Children>
</xsl:template>

</xsl:stylesheet>

Here是一个适用于Saxon 9.5和Xalan的修改 - 但不适用于libxslt。