对于输入XML,如:
<FlightOptions>
<item>
<Fares>
<item>
<FareClass>A</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>B</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>10</Seats>
</item>
<item>
<FareClass>C</FareClass>
<Fare>250</Fare>
<FareType>E</FareType>
<Seats>20</Seats>
</item>
<item>
<FareClass>N</FareClass>
<Fare>100</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>M</FareClass>
<Fare>200</Fare>
<FareType>F</FareType>
<Seats>50</Seats>
</item>
<item>
<FareClass>O</FareClass>
<Fare>300</Fare>
<FareType>F</FareType>
<Seats>20</Seats>
</item>
</Fares>
<Flight>
<FlightNumber>YY232</FlightNumber>
<Origin>JFK</Origin>
<Destination>LHR</Destination>
<DepTime>1300</DepTime>
<ArrTime>2000</ArrTime>
</Flight>
</item>
</FlightOptions>
对于上面的XML,我需要只保留几个票价/项目节点,我首先按FareType(E和F)分组,并保持项目从最便宜的票价开始,但如果座位是&gt; = 9则停止例如,由于A只有5个席位,我需要选择下一个最高票价B,但不是C.另外,如果Seats&gt; = 9,我需要将其限制为9个。
我可以进行分组和排序,但无法行走票价并应用逻辑来选择票价,只要该票价类型的座位<= 9。另一个复杂因素是输出XML必须重新排序Fares /项目,使得FareType E节点首先按Fare的降序排列,然后是N节点(如果存在于源中),然后其他FareType F节点按降序排列车费。
输出XML将是:
<FlightOptions>
<item>
<Fares>
<item>
<FareClass>B</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>A</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>N</FareClass>
<Fare>100</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>M</FareClass>
<Fare>200</Fare>
<FareType>F</FareType>
<Seats>9</Seats>
</item>
</Fares>
<Flight>
<FlightNumber>YY232</FlightNumber>
<Origin>JFK</Origin>
<Destination>LHR</Destination>
<DepTime>1300</Deptime>
<ArrTime>2000</ArrTime>
</Flight>
</item>
<FlightOptions>
一直试图阅读Muenchian分组示例,但我无法理解如何应用身份变换(因为我必须保持Flight结构以及Fares / item节点)。
谢谢!
答案 0 :(得分:0)
你可以在这个例子中不使用分组,因为你所做的一切都是排序,只是排除了一些元素。
因此,在匹配票价元素时,您可以对项元素进行排序,如此
<xsl:apply-templates select="item">
<xsl:sort select="FareType"/>
<xsl:sort select="Fare"/>
</xsl:apply-templates>
接下来,当您匹配每个商品元素时,您只需测试具有相同 FareType 的任何先前元素是否已大于9.如果没有这样的节点,然后因为你已经按票价排序,你知道要包含节点。
<xsl:template match="Fares/item">
<xsl:if test="not(preceding-sibling::item[FareType=current()/FareType][Seats > 9])">
<!-- copy node -->
</xsl:if>
这是完整的XSLT ......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Fares">
<xsl:copy>
<xsl:apply-templates select="item">
<xsl:sort select="FareType"/>
<xsl:sort select="Fare"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Fares/item">
<xsl:if test="not(preceding-sibling::item[FareType=current()/FareType][Seats > 9])">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
<xsl:template match="Seats[. > 9]">
<xsl:copy>9</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容:
<FlightOptions>
<item>
<Fares>
<item>
<FareClass>A</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>B</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>N</FareClass>
<Fare>100</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>M</FareClass>
<Fare>200</Fare>
<FareType>F</FareType>
<Seats>9</Seats>
</item>
</Fares>
<Flight>
<FlightNumber>YY232</FlightNumber>
<Origin>JFK</Origin>
<Destination>LHR</Destination>
<DepTime>1300</DepTime>
<ArrTime>2000</ArrTime>
</Flight>
</item>
</FlightOptions>
还要注意席位的模板匹配,然后将其限制为9。