给定输入XML
<FlightOptions>
<item>
<Fares>
<item>
<FareClass>T</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>Y</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>10</Seats>
</item>
<item>
<FareClass>R</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>L</FareClass>
<Fare>300</Fare>
<FareType>F</FareType>
<Seats>20</Seats>
</item>
<item>
<FareClass>K</FareClass>
<Fare>400</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>E</FareClass>
<Fare>500</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> 并应用XSL模板(感谢Tim C提供此功能!)-
<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>T</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>Y</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>R</FareClass>
<Fare>250</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>
<item>
<FareClass>L</FareClass>
<Fare>300</Fare>
<FareType>F</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>K</FareClass>
<Fare>400</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>E</FareClass>
<Fare>500</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> 我想对上面的输出做的是按照字母表的顺序(A,B,C,D...)替换FareClass标签。按照选择每一项的顺序。此外,我希望G和Y FareClass保持不变。如果您有关于XML/XSL的问题,我提出了问题#8074924,该问题已由Tim C解决。
输出的XML需要如下所示:
<FlightOptions>
<item>
<Fares>
<item>
<FareClass>A</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>Y</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>10</Seats>
</item>
<item>
<FareClass>B</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>C</FareClass>
<Fare>200</Fare>
<FareType>F</FareType>
<Seats>50</Seats>
</item>
<item>
<FareClass>D</FareClass>
<Fare>300</Fare>
<FareType>F</FareType>
<Seats>20</Seats>
</item>
<item>
<FareClass>E</FareClass>
<Fare>400</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>F</FareClass>
<Fare>500</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> 发布于 2012-10-17 15:32:56
如果我没理解错的话,您想要一个基于Tim的解决方案的解决方案,但是在输出中,所有的FareClass值都按照输出文档的顺序从A到Z重新排序,但G和Y保持不变。
我会使用这样的管道方法。请注意,阶段1是直接从Tim复制的,只能通过添加模式属性进行更改。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="xsl exslt">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="phase-1-output">
<xsl:apply-templates select="/" mode="phase-1" />
</xsl:variable>
<xsl:variable name="phase-2-output">
<xsl:apply-templates select="exslt:node-set($phase-1-output)" mode="phase-2" />
</xsl:variable>
<xsl:template match="/">
<xsl:copy-of select="$phase-2-output" />
</xsl:template>
<!-- ================ Phase One from Tim C ==============================-->
<xsl:template match="Fares" mode="phase-1">
<xsl:copy>
<xsl:apply-templates select="item" mode="phase-1" >
<xsl:sort select="FareType"/>
<xsl:sort select="Fare"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Fares/item" mode="phase-1">
<xsl:if test="not(preceding-sibling::item[FareType=current()/FareType][Seats > 9])">
<xsl:call-template name="identity-1" />
</xsl:if>
</xsl:template>
<xsl:template match="Seats[. > 9]" mode="phase-1">
<xsl:copy>9</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" name="identity-1" mode="phase-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="phase-1" />
</xsl:copy>
</xsl:template>
<!-- ================ Phase Two ============================================-->
<xsl:template match="@*|node()" name="identity-2" mode="phase-2">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="phase-2" />
</xsl:copy>
</xsl:template>
<xsl:template match="FareClass[.!='G'][.!='Y']" mode="phase-2">
<xsl:copy>
<xsl:variable name="raw-count">
<xsl:number count="item[(FareClass!='G') and (FareClass!='Y')]" />
</xsl:variable>
<xsl:number value="$raw-count + not($raw-count < 7)
+ not($raw-count < 25)" format="A" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>对原始编辑的样本输入执行...using操作,生成输出...
<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>D</FareClass>
<Fare>100</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>E</FareClass>
<Fare>200</Fare>
<FareType>F</FareType>
<Seats>50</Seats>
</item>
<item>
<FareClass>F</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>更新
感谢Surge提供了新的和改进的用例。使用我的解决方案,更新后的测试用例的输出是...
<FlightOptions>
<item>
<Fares>
<item>
<FareClass>A</FareClass>
<Fare>100</Fare>
<FareType>E</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>Y</FareClass>
<Fare>200</Fare>
<FareType>E</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>B</FareClass>
<Fare>250</Fare>
<FareType>E</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>C</FareClass>
<Fare>100</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>D</FareClass>
<Fare>200</Fare>
<FareType>F</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>E</FareClass>
<Fare>300</Fare>
<FareType>F</FareType>
<Seats>9</Seats>
</item>
<item>
<FareClass>F</FareClass>
<Fare>400</Fare>
<FareType>F</FareType>
<Seats>5</Seats>
</item>
<item>
<FareClass>H</FareClass>
<Fare>500</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>这与您声明的预期输出略有不同,但我相信这种差异可以通过您犯了一个错误(参见FareClass N)来解释。通过检查,我认为这是一个合格的结果。
更新2
糟了。我刚刚注意到了两个错误,并且已经纠正了它们。最初的错误模板是...
<xsl:variable name="phase-2-output">
<xsl:apply-templates select="/" mode="phase-2" />
</xsl:variable>和
<xsl:number count="item" />正确的代码应该是...
<xsl:variable name="phase-2-output">
<xsl:apply-templates select="exslt:node-set($phase-1-output)" mode="phase-2" />
</xsl:variable>和
<xsl:number count="item[(FareClass!='G') and (FareClass!='Y')]" />发布于 2012-10-17 18:03:11
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:apply-templates select="//Fares"/>
</xsl:template>
<xsl:template match="//Fares">
<xsl:for-each select="item">
<xsl:choose>
<xsl:when test="not(contains(FareClass,'G') or contains(FareClass,'Y'))">
<item>
<xsl:variable name="count">
<xsl:number count="item"/>
</xsl:variable>
<FareClass>
<xsl:choose>
<xsl:when test="position()>1">
<xsl:number format="A" value="position()-1"/>
</xsl:when>
<xsl:otherwise>
<xsl:number format="A"/>
</xsl:otherwise>
</xsl:choose>
</FareClass>
<xsl:copy-of select="child::*[position() > 1]"/>
</item>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>https://stackoverflow.com/questions/12924600
复制相似问题