首页 > 解决方案 > 在 XSLT 中应用模板但不起作用

问题描述

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

我试图简化它,并将应用模板移动到每个 for-1 中,然后我就让它工作了。

这是我的示例输入 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>

任何帮助表示赞赏。

谢谢

标签: xslt

解决方案


当您执行应用模板时,您已经定位在一个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>

推荐阅读