如何在XSLT中执行多条件检查

时间:2016-08-11 06:17:59

标签: xml xslt

我有一个具有多个属性的XML。我想执行条件检查,以便将元素移动到所需位置。我不知道可用于实现各自输出的术语或标签。

XML:

<Collection>

<Allparts>

    <part>
        <number>001</number>
        <material>Platinum</material>
        <price>High</price>
    </part>

    <part>
        <number>002</number>
        <material>Gold</material>
        <price>Medium</price>
    </part>

    <part>
        <number>003</number>
        <material>Silver</material>
        <price>Low</price>
    </part>


</Allparts>

<Allboms>

    <bom>
        <Part-number>001</Part-number>
    </bom>

    <bom>
        <Part-number>002</Part-number>
    </bom>

    <bom>
        <Part-number>003</Part-number>
    </bom>
</Allboms>

</Collection>

需要输出:

<Collection>

<Allparts>

    <part>
        <number>001</number>
        <material>Platinum</material>
        <price>High</price>
    </part>

    <part>
        <number>002</number>
        <material>Gold</material>
        <price>Medium</price>
    </part>

    <part>
        <number>003</number>
        <material>Silver</material>
        <price>Low</price>
    </part>


</Allparts>

<Allboms>

    <bom>
        <Part-number>001</Part-number>
        <material>Platinum</material>
        <price>High</price>
    </bom>

    <bom>
        <Part-number>002</Part-number>
        <material>Gold</material>
        <price>Medium</price>
    </bom>

    <bom>
        <Part-number>003</Part-number>
        <material>Silver</material>
        <price>Low</price>
    </bom>
</Allboms>

</Collection>

我尝试的XML:

<xsl:template match="bom">
    <xsl:copy>
        <xsl:choose >
            <xsl:when test= "../../bom/Part-number=../../part/number" >
            <xsl:apply-templates select= "../../part/material" mode="move" />
            </xsl:when >
        </xsl:choose >
        <xsl:apply-templates select= "@*|node()" />

    </xsl:copy>

    </xsl:template>

请建议更正:

1 个答案:

答案 0 :(得分:0)

以下XSLT-1.0解决方案应该这样做:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>


    <xsl:template match="Allboms/bom/Part-number">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
        <xsl:apply-templates select="/Collection/Allparts/part[number = current()]/material | /Collection/Allparts/part[number = current()]/price"/>
    </xsl:template>

    <!-- Identity transform template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

有两个模板:

  1. 身份转换模板:它按原样处理输入文档中的属性和节点。
  2. Part-number匹配的模板,该模板会复制自身并从material复制相应的priceAllparts
  3. 使用@JimGarrison建议的密钥

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:key name="material-by-num" match="/Collection/Allparts/part/material" use="../number"/>
        <xsl:key name="price-by-num" match="/Collection/Allparts/part/price" use="../number"/>
    
        <xsl:template match="Allboms/bom/Part-number">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
            <xsl:apply-templates select="key('material-by-num', .) | key('price-by-num', .)"/>
        </xsl:template>
    
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    
    </xsl:stylesheet>
    

    上面的XSLT使用两个键声明来匹配materialprice使用它们的兄弟number的值。 Part-number的模板使用这些键来复制所需的元素。