我是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>
感谢您的帮助。
谢谢
答案 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>