使用xslt版本1.0提取唯一属性值

时间:2019-05-22 14:30:07

标签: xml xslt grouping

我有一个要用XSLT 1.0版转换的xml。 (部分)输入如下所示:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <examples>
        <example>
            <firstAttribute id="first_attribute_id">
                <values>
                    <value>
                        <innerValue locale="en-US">EN_US_1_VAL</innerValue>
                        <innerValue locale="it-IT">IT_IT_1_VAL</innerValue>
                    </value>
                    <value>
                        <innerValue locale="it-IT">IT_IT_2_VAL</innerValue>
                    </value>
                    <value>
                        <innerValue locale="en-US">EN_US_2_VAL</innerValue>
                    </value>
                    <value>
                        <innerValue locale="it-IT">IT_IT_3_VAL</innerValue>
                        <innerValue locale="en-US">EN_US_3_VAL</innerValue>
                    </value>
                    <value>
                        <innerValue locale="it-IT">IT_IT_4_VAL</innerValue>
                    </value>
                </values>
            </firstAttribute>

            <extraData>
                <secondAttribute id="second_attribute_id">
                    <values>
                        <value>
                            <innerValue locale="en-US">US_1_VAL</innerValue>
                            <innerValue locale="it-IT">IT_1_VAL</innerValue>
                        </value>
                        <value>
                            <innerValue locale="en-US">US_2_VAL</innerValue>
                        </value>
                        <value>
                            <innerValue locale="it-IT">IT_2_VAL</innerValue>
                        </value>
                        <value>
                            <innerValue locale="en-US">US_3_VAL</innerValue>
                            <innerValue locale="it-IT">IT_3_VAL</innerValue>
                        </value>
                        <value>
                            <innerValue locale="it-IT">IT_4_VAL</innerValue>
                        </value>
                    </values>
                </secondAttribute>
            </extraData>
        </example>
    </examples>
</root>

并且我想按在locale属性内指定的语言环境分组特定于语言环境的数据-预期输出

<root>
    <testData>
        <test-attributes>
            <test-attribute name="first_attribute_id" xml:lang="en-US">
                <value>EN_US_1_VAL</value>
                <value>EN_US_2_VAL</value>
                <value>EN_US_3_VAL</value>
            </test-attribute>
            <test-attribute name="first_attribute_id" xml:lang="it-IT">
                <value>IT_IT_1_VAL</value>
                <value>IT_IT_2_VAL</value>
                <value>IT_IT_3_VAL</value>
                <value>IT_IT_4_VAL</value>
            </test-attribute>
        </test-attributes>
    </testData>
    <testData>
        <test-attributes>
            <test-attribute name="second_attribute_id" xml:lang="en-US">
                <value>US_1_VAL</value>
                <value>US_2_VAL</value>
                <value>US_3_VAL</value>
            </test-attribute>
            <test-attribute name="second_attribute_id" xml:lang="it-IT">
                <value>IT_1_VAL</value>
                <value>IT_2_VAL</value>
                <value>IT_3_VAL</value>
                <value>IT_4_VAL</value>
            </test-attribute>
        </test-attributes>
    </testData>
</root>

这是我正在使用的xslt文件,不会产生所需的输出:

<xsl:stylesheet
                xmlns:xml="http://www.w3.org/XML/1998/namespace"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xalan="http://xml.apache.org/xalan"
                version="1.0">

    <xsl:output method="xml" indent="yes" encoding="UTF-8" xalan:indent-amount="2"/>    
    <xsl:key name="firstLocales" match="firstAttribute/values/value/innerValue" use="@locale"/> 
    <xsl:key name="secondLocales" match="secondAttribute/values/value/innerValue" use="@locale"/>

    <xsl:template match="/">
        <xsl:element name="root">
            <xsl:for-each select="root/examples/example">
                <xsl:element name="testData">
                    <xsl:element name="test-attributes">
                        <xsl:for-each select="firstAttribute">
                            <xsl:for-each select="values/value/innerValue[generate-id() = generate-id(key('firstLocales',@locale)[1])]">
                                <xsl:element name="test-attribute">
                                    <xsl:attribute name="name"><xsl:value-of select="../../../@id"/></xsl:attribute>
                                    <xsl:attribute name="xml:lang"><xsl:value-of select="@locale"/></xsl:attribute>
                                    <xsl:variable name="CurrentLocale" select="@locale"/>
                                    <xsl:for-each select="../../../values/value/innerValue">
                                        <xsl:if test="@locale = $CurrentLocale">
                                            <xsl:element name="value">
                                                <xsl:value-of select="."/>
                                            </xsl:element>
                                        </xsl:if>
                                    </xsl:for-each>
                                </xsl:element>
                            </xsl:for-each>
                        </xsl:for-each>
                    </xsl:element>
                </xsl:element>

                <xsl:if test="extraData">
                    <xsl:for-each select="extraData">
                        <xsl:element name="testData">
                            <xsl:element name="test-attributes">
                                <xsl:for-each select="secondAttribute">
                                    <xsl:for-each select="values/value/innerValue[generate-id() = generate-id(key('secondLocales',@locale)[1])]">
                                        <xsl:element name="test-attribute">
                                            <xsl:attribute name="name"><xsl:value-of select="../../../@id"/></xsl:attribute>
                                            <xsl:attribute name="xml:lang"><xsl:value-of select="@locale"/></xsl:attribute>
                                            <xsl:variable name="CurrentLocale" select="@locale"/>
                                            <xsl:for-each select="../../../values/value/innerValue">
                                                <xsl:if test="@locale = $CurrentLocale">
                                                    <xsl:element name="value">
                                                        <xsl:value-of select="."/>
                                                    </xsl:element>
                                                </xsl:if>
                                            </xsl:for-each>
                                        </xsl:element>
                                    </xsl:for-each>
                                </xsl:for-each>
                            </xsl:element>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:if>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

我从here开始使用解决方案,但是显然我做错了。第一部分(使用firstAttribute的地方)成功转换,但是第二部分仍然为空-当前输出

<root>
    <testData>
        <test-attributes>
            <test-attribute name="first_attribute_id" xml:lang="en-US">
                <value>EN_US_1_VAL</value>
                <value>EN_US_2_VAL</value>
                <value>EN_US_3_VAL</value>
            </test-attribute>
            <test-attribute name="first_attribute_id" xml:lang="it-IT">
                <value>IT_IT_1_VAL</value>
                <value>IT_IT_2_VAL</value>
                <value>IT_IT_3_VAL</value>
                <value>IT_IT_4_VAL</value>
            </test-attribute>
        </test-attributes>
    </testData>
    <testData>
        <test-attributes/>
    </testData>
</root>

请帮助我进行此转换-修复我的.xslt文件或使用其他方法-我必须坚持使用XSLT 1.0版。 预先谢谢你:)

0 个答案:

没有答案