使用XSLT在循环中条件匹配时向元素添加元素

时间:2017-09-12 03:20:01

标签: xml xslt

我正在尝试在XSLT 1.0中实现这一点,以下是条件 在任何时候,ADT的发生都不仅仅发生在INF一个ADT应该只有INF标签的一个姓氏,名字和DOB细节 如果ADT标签超过INF标签,则应将第一个ADT标签标记为INF,并且如果ADT标签不应附加任何INF,则应休息。不需要更改子标记,但它应该出现在输出中。

我正在尝试使用XSLT实现以下输出,但无法完全修复它,任何帮助都将非常感激。

在XSLT下面需要帮助进行转换

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <travelerGroup>
            <xsl:for-each select="/travelerGroup/traveler">
                <xsl:if test="travelerInfo/travelerTypeCode != 'INF' ">
                    <traveler>
                        <travelerInfo>
                            <elementNumber>
                                <xsl:value-of select="travelerInfo/elementNumber" />
                            </elementNumber>
                            <travelerTypeCode>
                                <xsl:value-of select="travelerInfo/travelerTypeCode" />
                            </travelerTypeCode>
                            <travelerDetails>
                                <firstName>
                                    <xsl:value-of select="concat(travelerInfo/travelerDetails/firstName" />
                                </firstName>
                                <surname>
                                    <xsl:value-of select="travelerInfo/travelerDetails/surname" />
                                </surname>
                                <xsl:if test="travelerInfo/travelerTypeCode = 'CHD' ">
                                    <dateOfBirth>
                                        <xsl:value-of select="travelerInfo/travelerDetails/dateOfBirth" />
                                    </dateOfBirth>
                                </xsl:if>
                            </travelerDetails>
                            <xsl:if test="travelerInfo/travelerTypeCode != 'CHD' ">
                                <xsl:variable name="i" select="position()" />
                                <xsl:for-each select="/traveler[travelerInfo/travelerTypeCode = 'INF'][$i]">
                                    <xsl:if test="travelerInfo/travelerTypeCode = 'INF' ">
                                        <infant>
                                            <surname>
                                                <xsl:value-of select="travelerInfo/travelerDetails/surname" />
                                            </surname>
                                            <firstName>
                                                <xsl:value-of select="travelerInfo/travelerDetails/firstName" />
                                            </firstName>
                                            <dateOfBirth>
                                                <xsl:value-of select="travelerInfo/travelerDetails/dateOfBirth" />
                                            </dateOfBirth>
                                        </infant>
                                    </xsl:if>
                                </xsl:for-each>
                            </xsl:if>
                        </travelerInfo>
                    </traveler>
                </xsl:if>
            </xsl:for-each>
        </travelerGroup>
    </xsl:template>
</xsl:stylesheet>

输入XML:

<travelerGroup>
<traveler>
    <travelerInfo>
        <elementNumber>1</elementNumber>
        <travelerTypeCode>ADT</travelerTypeCode>
        <travelerDetails>
            <firstName>Adult One</firstName>
            <surname>Surname</surname>
        </travelerDetails>
    </travelerInfo>
</traveler>
<traveler>
    <travelerInfo>
        <elementNumber>2</elementNumber>
        <travelerTypeCode>ADT</travelerTypeCode>
        <travelerDetails>
            <firstName>Adult Two</firstName>
            <surname>Surname</surname>
        </travelerDetails>
    </travelerInfo>
</traveler>
<traveler>
    <travelerInfo>
        <travelerTypeCode>INF</travelerTypeCode>
        <elementNumber>3</elementNumber>
        <travelerDetails>
            <firstName>Infant One</firstName>
            <surname>Surname</surname>
            <dateOfBirth>2016-01-06</dateOfBirth>
        </travelerDetails>
    </travelerInfo>
</traveler>
<traveler>
    <travelerInfo>
        <travelerTypeCode>INF</travelerTypeCode>
        <elementNumber>4</elementNumber>
        <travelerDetails>
            <firstName>Infant Two</firstName>
            <surname>Surname</surname>
            <dateOfBirth>2017-01-06</dateOfBirth>
        </travelerDetails>
    </travelerInfo>
</traveler>
<traveler>
    <travelerInfo>
        <elementNumber>5</elementNumber>
        <travelerTypeCode>ADT</travelerTypeCode>
        <travelerDetails>
            <firstName>Adult Three</firstName>
            <surname>Surname</surname>
        </travelerDetails>
    </travelerInfo>
</traveler>
<traveler>
    <travelerInfo>
        <elementNumber>6</elementNumber>
        <travelerTypeCode>CHD</travelerTypeCode>
        <travelerDetails>
            <firstName>Child One</firstName>
            <surname>Surname</surname>
            <dateOfBirth>2013-01-06</dateOfBirth>
        </travelerDetails>
    </travelerInfo>
</traveler>
</travelerGroup>

预期产出:

<travelerGroup>
<traveler>
    <elementNumber>1</elementNumber>
    <travelerTypeCode>ADT</travelerTypeCode>
    <travelerDetails>
        <firstName>Adult One</firstName>
        <surname>Surname</surname>
        <middleName />
    </travelerDetails>
    <infant>
        <surname>Infant One</surname>
        <firstName>Surname</firstName>
        <dateOfBirth>2016-01-06</dateOfBirth>
    </infant>
</traveler>
<traveler>
    <elementNumber>2</elementNumber>
    <travelerTypeCode>ADT</travelerTypeCode>
    <travelerDetails>
        <firstName>Adult Two</firstName>
        <surname>Surname</surname>
        <middleName />
    </travelerDetails>
    <infant>
        <surname>Infant Two</surname>
        <firstName>Surname</firstName>
        <dateOfBirth>2017-01-06</dateOfBirth>
    </infant>
</traveler>
<traveler>
    <elementNumber>5</elementNumber>
    <travelerTypeCode>ADT</travelerTypeCode>
    <travelerDetails>
        <firstName>Adult Three</firstName>
        <surname>Surname</surname>
        <middleName />
    </travelerDetails>
</traveler>
 <traveler>
    <elementNumber>6</elementNumber>
    <travelerTypeCode>CHD</travelerTypeCode>
    <travelerDetails>
        <firstName>Child One</firstName>
        <surname>Surname</surname>
        <dateOfBirth>2013-01-06</dateOfBirth>
    </travelerDetails>
</traveler>  
</travelerGroup>   

1 个答案:

答案 0 :(得分:1)

输出中有几个小故障。 <firstName>的{​​{1}}和<surname>的值互换。成人的INF也不在输入中,但在输出中显示。如果输出中需要<middleName>,则可以对以下XSL进行必要的更改。

XSLT

<middleName>

输出

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="travelerGroup">
        <xsl:copy>
            <!-- loop through all the adults -->
            <xsl:for-each select="traveler/travelerInfo[travelerTypeCode = 'ADT']">
                <traveler>
                    <xsl:variable name="adtIndex" select="position()" />
                    <!-- copy nodes for adult -->
                    <xsl:copy-of select="@* | node()" />

                    <!-- loop through all infants -->
                    <xsl:for-each select="//traveler/travelerInfo[travelerTypeCode = 'INF']">
                        <xsl:variable name="infIndex" select="position()" />

                        <!-- compare adult node index with infant node index -->
                        <xsl:if test="$adtIndex = $infIndex">
                            <infant>
                                <!-- copy infant nodes within adult -->
                                <xsl:copy-of select="travelerDetails/firstName" />
                                <xsl:copy-of select="travelerDetails/surname" />
                                <xsl:copy-of select="travelerDetails/dateOfBirth" />
                            </infant>
                        </xsl:if>
                    </xsl:for-each>
                </traveler>
            </xsl:for-each>
            <!-- loop through child and copy them as is -->
            <xsl:for-each select="//traveler/travelerInfo[travelerTypeCode = 'CHD']" >
                <traveler>
                    <xsl:copy-of select="@* | node()" />
                </traveler>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>