使用XSLT有条件地处理XML文件

时间:2018-04-20 21:06:04

标签: xml xslt xslt-1.0

我在使用xslt转换xml文件时遇到了困难。我的标准是输入xml中是否有特定节点,然后将xsl逻辑应用于所有元素。如果该节点不存在,请不要应用逻辑。我有的xsl如下。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8"/>
    <xsl:template match="Root/Order">
        <xsl:choose>
            <xsl:when test="Order1/task or Order2/task or task">
                <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
                <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
            </xsl:when>
            <xsl:otherwise></xsl:otherwise>
        </xsl:choose>
        <xsl:for-each select="task">
                <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
                <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
        </xsl:for-each>
        <xsl:for-each select="Order1">
            <xsl:for-each select="task">
                <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
                <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
            </xsl:for-each>
        </xsl:for-each>
        <xsl:for-each select="Order2">
            <xsl:for-each select="task">
                <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
                <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
                <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

输入文件结构如下

    <?xml version="1.0" encoding="UTF-8"?>
    <Root>
    <Order>
        <cust>
            <Date>2018-04-16</Date>
            <name>abc</name>
            <code>xyz10</code>
            <custId>abc123</custId>
            <System>main</System>
            <Number>TANK</Number>
        </cust>
        <make>
            <Indi>A</Indi>
          <Number>BA22299</Number>
          <Status>O</Status>
          <Code>SEK</Code>
          <Class>3B</Class>
        </make>
        <Order1> <!-- It can also be Order2 -->
            <task>  
                <tasks>
                    <lno>010</lno>
                    <val>100</val>
                </tasks>
            </task>
        </Order1>
        <task>  
            <tasks>
                <lno>010</lno>
                <val>100</val>
            </tasks>
        </task>

    </Order>
</Root>

在上面的例子中,我想检查输入中是否有'task'节点,然后应用模板。

我尝试了不同的情况,但每次xsl都在处理输入文件而不管'task'节点。

  1. 我为每个循环内部的<xsl: if test = task>内部尝试了<xsl: if test = Order1/task>

  2. 我尝试了另一个选择第一个条件后的条件。

    <xsl:choose> 
       <xsl:when test = "Order1/task or Order2/task or task">
          <!-- for each from above xsl >
        </xsl:when>
    <xsl:choose> 
    
  3. 但我无法获得所需的结果。请告知我在哪里做错了,以及在输入文件中的节点上编写条件逻辑的更好方法。

    以上输入的输出如下所示。

    |abc123|main|TANK|BA22299|O|A|SEK||
    ||||||||010|100
    ||||||||010|100
    

1 个答案:

答案 0 :(得分:0)

仅当任务节点存在时,才应用模板的口头描述转换为

<xsl:template match="/">
  <xsl:apply-templates select="Root/Order[Order1/task or Order2/task or task]"/>
<xsl:template>

然后您可以从模板中删除支票,即将其更改为

<xsl:template match="Root/Order">
            <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
            <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
    <xsl:for-each select="task">
            <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
            <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
    <xsl:for-each select="Order1">
        <xsl:for-each select="task">
            <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
            <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
        </xsl:for-each>
    </xsl:for-each>
    <xsl:for-each select="Order2">
        <xsl:for-each select="task">
            <xsl:value-of select="ID"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/custId"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/System"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="cust/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Number"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Status"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Indi"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="make/Code"/><xsl:text>|</xsl:text> 
            <xsl:value-of select="tasks/lno"/><xsl:text>|</xsl:text>
            <xsl:value-of select="tasks/val"/><xsl:text>&#xa;</xsl:text>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>