【问题标题】:XSL for-each combine different operatorsXSL for-each 结合不同的运算符
【发布时间】:2016-07-04 13:59:57
【问题描述】:

我有这个 XML 文件,我需要通过三种方式对其进行过滤:

1) 颜色应该是红色或绿色,所有其他颜色都应该被过滤掉

2) 类别可以是任何类别,除了 catB

3) 状态可以是任何状态,除了 MISSING 或 DAMAGED

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="items.xsl"?>
<list>
<item>
<description>Green catA Damaged</description>
<include>N</include>
<colour>GREEN</colour>
<category>catA</category>
<status>DAMAGED</status>
</item>
<item>
<description>Red catA OK</description>
<include>Y</include>
<colour>RED</colour>
<category>catA</category>
<status>OK</status>
</item>
<item>
<description>Green catB OK</description>
<include>N</include>
<colour>GREEN</colour>
<category>catB</category>
<status>OK</status>
</item>
<item>
<description>Red catB OK</description>
<include>N</include>
<colour>RED</colour>
<category>catB</category>
<status>OK</status>
</item>
<item>
<description>Blue catB OK</description>
<include>N</include>
<colour>BLUE</colour>
<category>catC</category>
<status>OK</status>
</item>
<item>
<description>Yellow catC OK</description>
<include>N</include>
<colour>YELLOW</colour>
<category>catC</category>
<status>OK</status>
</item>
<item>
<description>Green catA OK</description>
<include>Y</include>
<colour>GREEN</colour>
<category>catA</category>
<status>OK</status>
</item>
<item>
<description>Green catB Missing</description>
<include>N</include>
<colour>GREEN</colour>
<category>catB</category>
<status>MISSING</status>
</item>
<item>
<description>Red catB Missing</description>
<include>N</include>
<colour>RED</colour>
<category>catA</category>
<status>MISSING</status>
</item>
<item>
<description>Red catC Damaged</description>
<include>N</include>
<colour>RED</colour>
<category>catC</category>
<status>DAMAGED</status>
</item>
</list>

我为第一个(正面)条件尝试了一个 for-each,并为其他两个(负面)条件尝试了另一个 for-each - 但是我到底应该如何将它们组合成一个?或者,是否有另一种更好的替代方法来代替 for-each。 谷歌搜索和检查三本书都没有给我答案,所以我有一种奇怪的感觉,我完全错了.....

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
    <list>

            <!-- "positive" statement
        <xsl:for-each select="list/item[colour='GREEN' or colour='RED']">

            "negative" statement
        <xsl:for-each select="list/item[status!='MISSING'][status!='DAMAGED'][category!='catB']">
            -->


            <xsl:sort select="description"/>

                <itemline>
                    <description><xsl:value-of select="description"/></description>
                    <include><xsl:value-of select="include"/></include>
                    <colour><xsl:value-of select="colour"/></colour>
                    <category><xsl:value-of select="category"/></category>
                    <status><xsl:value-of select="status"/></status>
                </itemline>


        </xsl:for-each>
    </list>
</xsl:template>

</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt foreach operators


    【解决方案1】:

    我有这个 XML 文件,我需要通过三种方式对其进行过滤:

    1) 颜色应为红色或绿色,所有其他颜色应过滤 离开

    2) 类别可以是任何类别,除了 catB

    3) 状态可以是任何状态,除了 MISSING 或 DAMAGED

    我会这样写:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
      <xsl:template match="/*">
        <xsl:apply-templates select=
         "item[colour[. = 'RED' or . = 'GREEN'] 
              and not(category='catB' or status[. = 'MISSING' or . = 'DAMAGED'])]">
          <xsl:sort select="description"/>
        </xsl:apply-templates>
      </xsl:template>
    
      <xsl:template match="item">
        <itemline><xsl:copy-of select="*"/></itemline>
      </xsl:template>
    </xsl:stylesheet>
    

    如果使用&lt;xsl:for-each&gt;很重要(这通常不是最好的 XSLT 做法),上面的等价于这种转换:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
      <xsl:template match="/*">
        <xsl:for-each select=
         "item[colour[. = 'RED' or . = 'GREEN'] 
              and not(category='catB' or status[. = 'MISSING' or . = 'DAMAGED'])]">
          <xsl:sort select="description"/>
          <itemline><xsl:copy-of select="*"/></itemline>
        </xsl:for-each>
      </xsl:template>
    </xsl:stylesheet>
    

    当对提供的 XML 文档应用这两种转换时,会产生所需的正确结果:

    <itemline>
       <description>Green catA OK</description>
       <include>Y</include>
       <colour>GREEN</colour>
       <category>catA</category>
       <status>OK</status>
    </itemline>
    <itemline>
       <description>Red catA OK</description>
       <include>Y</include>
       <colour>RED</colour>
       <category>catA</category>
       <status>OK</status>
    </itemline>
    

    一个有用的快捷表达方式:

    代替:

    myElem = value1 or myElem = value2 or myElem = value3 or myElem = value4 or myElem = value5 
    

    可以这样写:

    contains('|value1|value2|value3|value4|value5|', concat('|',myElem, '|'))
    

    或者,如果第一个参数字符串是变量$myValues 的值:

    contains($myValues, concat('|',myElem, '|')) 
    

    同样,myElem 值的快捷方式不是众多值之一:

    not(contains($myValues, concat('|',myElem, '|'))) 
    

    【讨论】:

      【解决方案2】:

      1) 颜色应为红色或绿色,所有其他颜色应过滤 离开

      2) 类别可以是任何类别,除了 catB

      3) 状态可以是任何状态,除了 MISSING 或 DAMAGED

      怎么样:

      XSLT 1.0

      <xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
      
      <xsl:template match="/list">
          <list>
              <xsl:for-each select="item
                                    [colour='RED' or colour='GREEN']
                                    [not(category='catB')]
                                    [not(status='MISSING' or status='DAMAGED')]">
                  <xsl:sort select="description"/>
                  <itemline>
                      <xsl:copy-of select="*"/>
                  </itemline>
              </xsl:for-each>
          </list>
      </xsl:template>
      
      </xsl:stylesheet>
      

      【讨论】:

        猜你喜欢
        • 2012-06-25
        • 2011-01-14
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 2012-10-11
        • 1970-01-01
        • 2023-01-11
        • 2016-09-15
        相关资源
        最近更新 更多