在XSLT中应用模板,无法正常工作

时间:2019-04-05 11:35:52

标签: xslt

我是XSLT的新手,我正在尝试将模板应用于通过嵌套的for-each函数到达的特定节点。

我试图简化它,并将apply-templates仅移动了1个for-for,然后就可以使用它了。

这是我的示例输入xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<getPartMasterDataCompleteResponse >
    <result>
        <partMasterDataCompletes>
            <partMasterDataComplete>
                <part>A0001506450</part>
                <version>11</version>
                <partMasterData>
                    <language>german</language>
                    <part>A1234567890</part>
                    <releaseDateFrom>2018-09-06T08:52:18+02:00</releaseDateFrom>
                    <testTag>
                        <test></test>
                        <test></test>
                        <test></test>
                    </testTag>
                </partMasterData>
            </partMasterDataComplete>
        </partMasterDataCompletes>
    </result>
</getPartMasterDataCompleteResponse>

这是我正在使用的xslt:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="getPartMasterDataCompleteResponse/result/partMasterDataCompletes">
        <xsl:for-each select="partMasterDataComplete">
            <Part>
                <UserData>
                    <xsl:for-each select="partMasterData/*">
                        <xsl:if test="not(*)">
                            <xsl:choose>
                                <xsl:when test="local-name() = 'part'">
                                    <xsl:apply-templates select="part"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <UserValue>
                                        <xsl:attribute name="title">
                                            <xsl:value-of select="local-name()"/>
                                        </xsl:attribute>
                                        <xsl:attribute name="value">
                                            <xsl:value-of select="current()"/>
                                        </xsl:attribute>
                                    </UserValue>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:if>
                    </xsl:for-each>
                </UserData>
            </Part>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="part">
        <UserValue title="PartNumber">
            <xsl:attribute name="value">
                <xsl:value-of select="current()"/>
            </xsl:attribute>
        </UserValue>
    </xsl:template>

</xsl:stylesheet>

我从在线转换工具获得的结果是:

<Part>
   <UserData>
      <UserValue title="language" value="german"/>
      <UserValue title="releaseDateFrom" value="2018-09-06T08:52:18+02:00"/>
   </UserData>
</Part>

我期望的是:

<Part>
   <UserData>
      <UserValue title="language" value="german"/>
      <UserValue title="PartNumber" value="A0001506450"/>
      <UserValue title="releaseDateFrom" value="2018-09-06T08:52:18+02:00"/>
   </UserData>
</Part>

感谢您的帮助。

谢谢

1 个答案:

答案 0 :(得分:1)

当您应用模板时,您已经位于part元素上,因此通过执行<xsl:apply-templates select="part"/>您实际上在当前元素上寻找名为part的子元素。 (即实际上与执行<xsl:apply-templates select="child::part"/>相同)

您要将模板应用于当前元素,请执行以下操作:

<xsl:apply-templates select="."/>

或者,如果您真的想使其明确...

<xsl:apply-templates select="self::part"/>

顺便说一句,通过更好地使用xsl:apply-templates并使用属性值模板来创建属性,可以大大简化XSLT。

尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="getPartMasterDataCompleteResponse/result/partMasterDataCompletes">
        <xsl:for-each select="partMasterDataComplete">
            <Part>
                <UserData>
                    <xsl:apply-templates select="partMasterData/*[not(*)]" />
                </UserData>
            </Part>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="partMasterData/*">
        <UserValue title="{local-name()}" value="{current()}" />
    </xsl:template>

    <xsl:template match="part">
        <UserValue title="PartNumber" name="{current()}" />
    </xsl:template>
</xsl:stylesheet>