我是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>
....
表示与上述相同的订单
我需要输出:
<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获取解决方案吗?
答案 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。