Xslt :从 XML 到 CSV,其中我们有多个重复出现的根项

Xslt : From XML to CSV where we have multiple root items that are reoccuring

我有 xml 格式的数据,其中有两个根标签多次出现。这两个根由键元素连接。意思是 root1 的一半数据在 root2.

<sample_static>

    <root1>
        <elemnent1_key>1112</element1_key>
        <elemnent2>boss</elemnent2>
        <elemnent3>movie</elemnent3>
        <elemnent4>entertainment</elemnent4>
    </root1>
    <root1>
        <elemnent1_key>1113</element1_key>
        <elemnent2>king</elemnent2>
        <elemnent3>position</elemnent3>
        <elemnent4>entertainer</elemnent4>
    </root1>
    <root1>
        <elemnent1_key>1114</element1_key>
        <elemnent2>employee</elemnent2>
        <elemnent3>human</elemnent3>
        <elemnent4>puppet</elemnent4>
    </root1>
    .
    .
    .
    .

    <root2>
        <elemnent5_key>1112</element5_key>
        <elemnent6>good</elemnent6>
        <elemnent7>hit</elemnent7>
        <elemnent8>earning</elemnent8>
    </root2>
    <root2>
        <elemnent5_key>1113</element5_key>
        <elemnent6>loser</elemnent6>
        <elemnent7>duffer</elemnent7>
        <elemnent8>history</elemnent8>
    </root2>
    <root2>
        <elemnent5_key>1114</element5_key>
        <elemnent6>onsite</elemnent6>
        <elemnent7>rejected</elemnent7>
        <elemnent8>switch</elemnent8>
    </root2>
    .
    .
    .
    .

</sample_static>

期望输出

所以我想使用 XSLT 映射制作以下格式的 csv 文件。

element1_key|elemnent2|elemnent3|elemnent4|elemnent6|elemnent7|elemnent8

1112|boss|movie|entertainment|good|hit|earning

1113|king|position|entertainer|loser|duffer|history

1114|employee|human|puppet|onsite|rejected|switch

我想连接根 1 元素和根 2 元素并仅使用 XSLT 形成一行。

注意:有很多 ROOT1 one 标签和 ROOT2 标签。对于示例,我给出了 3 个 root1 和 3 个 root2 标签来演示连接。

Root1的第一个数据可以用element1_key1112和element5_key1112

连接

我们该怎么做?任何想法

使用 key:

可以很简单地完成
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />

<xsl:key name="root2" match="root2" use="element5_key" />

<xsl:template match="/sample_static">
    <xsl:for-each select="root1">
        <xsl:for-each select="*|key('root2', element1_key)/*[not(self::element5_key)] ">
            <xsl:value-of select="." />
            <xsl:if test="position()!=last()">
                <xsl:text>|</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

编辑

if there is no root2 for any root 1 the field should be blank.. for example if one root data is like 1113|a|b|c|d|e|f the other can be like 1114|x|y|||||

如果你事先知道root2中有多少个元素,你可以这样做:

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

<xsl:key name="root2" match="root2" use="element5_key" />

<xsl:template match="/sample_static">
    <xsl:for-each select="root1">
        <xsl:for-each select="*">
            <xsl:value-of select="." />
            <xsl:text>|</xsl:text>
        </xsl:for-each>
        <xsl:variable name="root2" select="key('root2', element1_key)"/>
        <xsl:choose>
            <xsl:when test="$root2">
                <xsl:for-each select="$root2/*[not(self::element5_key)]">
                    <xsl:value-of select="." />
                    <xsl:if test="position()!=last()">
                        <xsl:text>|</xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>|||</xsl:otherwise>
        </xsl:choose>
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>