我最近刚开始学习XSLT,并提出了一个场景。源代码和目标结构完全相同,可以使用下面的代码完成:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="node()|@*" /></xsl:copy>
</xsl:template>
</xsl:stylesheet>
但我的要求是仅在满足其中一个条件时才创建目标节点。
示例
VNum eq 999
源和目标应如下所示:
来源
<POExt>
<SD>01</SD>
<PODet>
<PNum schemeAgencyID="TEST">12345678</PNum>
<VNum>999</VNum>
</PODet>
<PODet>
<PNum schemeAgencyID="">45654654</PNum>
<VNum>001</VNum>
</PODet>
</POExt>
目标
<POExt>
<SD>01</SD>
<PODet>
<PNum schemeAgencyID="TEST">12345678</PNum>
<VNum>999</VNum>
</PODet>
</POExt>
每次符合VNum标准时, <PODet>
都会重复,如果<PODet>
都不符合条件就可以
<POExt>
<SD>01</SD>
</POExt>
想要使用复制和应用模板完成此任务,我们将非常感谢您的帮助。
谢谢..
答案 0 :(得分:3)
使用身份规则时,您需要通过匹配模板覆盖元素。
在您的情况下,您不希望复制不符合特定条件的PODet
元素。根据否定逻辑,您只需“关闭”与您的条件不匹配的节点。例如:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PODet[not(VNum/text()=999)]"/>
</xsl:stylesheet>
如果您的VNum
是可变的,请说明您的转换的输入参数,在XSLT 2.0中您可以这样做:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:param name="VNum" select="999"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PODet[not(VNum/text()=$VNum)]"/>
</xsl:stylesheet>
在XSLT 1.0中,模板匹配模式中不允许使用变量,因此必须在模板中包含条件检查。例如,您只能将模板应用于符合条件的元素:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="VNum" select="999"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PODet">
<xsl:apply-templates select="VNum[text()=$VNum]"/>
</xsl:template>
<xsl:template match="VNum">
<xsl:copy-of select=".."/>
</xsl:template>
</xsl:stylesheet>