基于子元素XSLT删除元素

时间:2009-12-15 20:49:31

标签: xml xslt duplicates

我是Stack Overflow和XSLT的新手。我根据一些子元素条件从输出中删除重复的条目时遇到问题。

以下是我的XML示例:

<partyorders>    
    <order>  
        <day>12</day>
        <month>05</month>  
        <year>2000</year>  
        <amount>5000.00</amount>  
        <decision>pending</decision>  
    </order>  
    <order>  
        <day>19</day>  
        <month>04</month>  
        <year>2000</year>  
        <amount>2000.00</amount>  
        <decision>pending</decision>  
    </order>  
    <order>  
        <day>19</day>  
        <month>04</month>  
        <year>2000</year>  
        <amount>2000.00</amount>  
        <decision>reserved</decision>  
    </order> 
     <order>  
        <day>05</day>  
        <month>04</month>  
        <year>2000</year>  
        <amount>1000.00</amount>  
        <decision>pending</decision>  
    </order>  
    <order>  
        <day>05</day>  
        <month>04</month>  
        <year>2000</year>  
        <amount>1000.00</amount>  
        <decision>reserved</decision>  
    </order> 
    <order>
        ....
    </order>
</partyorders>  

....表示与上述相同的订单

我需要输出:

  1. 只有一个处于暂挂/批准状态的订单。
  2. 如果有两个只有不同状态的订单,我想在通过比较元素<day><month><year><amount> <确认后才显示保留订单/ LI>

    我想要基于<day><month><year><amount><decision>标记的以下输出:

    <restrntpartyorders>    
        <restrntorder>  
            <partyday>12</partyday>
            <partymonth>05</partymonth>  
            <partyyear>2000</partyyear>  
            <partyamount>5000.00</partyamount>  
            <partydecision>pending</partydecision>  
        </restrntorder>  
        <restrntorder>  
            <partyday>19</partyday>  
            <partymonth>04</partymonth>  
            <partyyear>2000</partyyear>  
            <partyamount>2000.00</partyamount>  
            <partydecision>reserved</partydecision>  
        </restrntorder>  
        <restrntorder>  
            <partyday>05</partyday>  
            <partymonth>04</partymonth>  
            <partyyear>2000</partyyear>  
            <partyamount>1000.00</partyamount>  
            <partydecision>reserved</partydecision>  
        </restrntorder> 
        <restrntorder>
            ....
        </restrntorder>
    </restrntpartyorders>  
    

    有人可以帮助我使用XSLT 1.0获取解决方案吗?

2 个答案:

答案 0 :(得分:1)

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output indent="yes" encoding="utf-8" />

  <!-- index order elements by year, month, day, amount -->
  <xsl:key 
    name="kOrdersByDate" 
    match="order" 
    use="concat(year, '-', month, '-', day, '$', amount)"
  />

  <xsl:template match="order">
    <!-- select all orders of same date and amount -->
    <xsl:variable name="same" select="
      key('kOrdersByDate', concat(year, '-', month, '-', day, '$', amount))
    " />
    <!-- of those, select the first 'reserved' order -->
    <xsl:variable name="same-reserved" select="
      $same[decision = 'reserved']
    " />

    <!-- check that either: 
      1. no other equal order, e.g. count($same) = 1, or
      2. reseverd order exists, take it
      3. no reseverd order exists, take the first "same" order
    -->
    <xsl:if test="
      count($same) = 1 
      or 
      ($same-reserved and generate-id() = generate-id($same-reserved[1]))
      or
      (not($same-reserved) and generate-id() = generate-id($same[1]))
    ">
      <!-- rename order -> restrntorder -->
      <restrntorder>
        <xsl:apply-templates select="*" />
      </restrntorder>
    </xsl:if>
  </xsl:template>

  <!-- rename partyorders -> restrntpartyorders -->
  <xsl:template match="partyorders">
    <restrntpartyorders>
      <xsl:apply-templates select="order" />
    </restrntpartyorders>
  </xsl:template>

  <!-- rename day etc. -> partyday etc. -->
  <xsl:template match="order/*">
    <xsl:element name="party{local-name()}">
      <xsl:value-of select="." />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

输出:

<?xml version="1.0" encoding="utf-8"?>
<restrntpartyorders>
    <restrntorder>
        <partyday>12</partyday>
        <partymonth>05</partymonth>
        <partyyear>2000</partyyear>
        <partyamount>5000.00</partyamount>
        <partydecision>pending</partydecision>
    </restrntorder>

    <restrntorder>
        <partyday>19</partyday>
        <partymonth>04</partymonth>
        <partyyear>2000</partyyear>
        <partyamount>2000.00</partyamount>
        <partydecision>reserved</partydecision>
    </restrntorder>

    <restrntorder>
        <partyday>05</partyday>
        <partymonth>04</partymonth>
        <partyyear>2000</partyyear>
        <partyamount>1000.00</partyamount>
        <partydecision>reserved</partydecision>
    </restrntorder>
    <restrntorder>
        ....
    </restrntorder>
</restrntpartyorders>

答案 1 :(得分:0)

相关的xsl:template内容为:

<partyorders>
  <xsl:for-each select="/partyorders/order">
    <xsl:if test="count(following-sibling::order[day = current()/day and month = current()/month etc etc]) = 0">
      <xsl:copy-of select="." />
    </xsl:if>
  </xsl:for-each>
</partyorders>

这是O(N ^ 2)tho,我不建议在负载下使用XSLT。