COPY问题应用模板XSLT

时间:2011-06-16 04:38:59

标签: xslt

我最近刚开始学习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>

想要使用复制和应用模板完成此任务,我们将非常感谢您的帮助。

谢谢..

1 个答案:

答案 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>