首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将XML值替换为XSL转换中的连续字母

将XML值替换为XSL转换中的连续字母
EN

Stack Overflow用户
提问于 2012-10-17 06:43:56
回答 2查看 387关注 0票数 0

给定输入XML

代码语言:javascript
复制
<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提供此功能!)-

代码语言:javascript
复制
 <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 -

代码语言:javascript
复制
<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需要如下所示:

代码语言:javascript
复制
<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> 
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-17 15:32:56

如果我没理解错的话,您想要一个基于Tim的解决方案的解决方案,但是在输出中,所有的FareClass值都按照输出文档的顺序从A到Z重新排序,但G和Y保持不变。

我会使用这样的管道方法。请注意,阶段1是直接从Tim复制的,只能通过添加模式属性进行更改。

代码语言:javascript
复制
<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 &lt;  7)
                                      + not($raw-count &lt; 25)" format="A" />
      </xsl:copy> 
   </xsl:template> 


</xsl:stylesheet>

对原始编辑的样本输入执行...using操作,生成输出...

代码语言:javascript
复制
<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提供了新的和改进的用例。使用我的解决方案,更新后的测试用例的输出是...

代码语言:javascript
复制
<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

糟了。我刚刚注意到了两个错误,并且已经纠正了它们。最初的错误模板是...

代码语言:javascript
复制
<xsl:variable name="phase-2-output">
  <xsl:apply-templates select="/" mode="phase-2" />
</xsl:variable>

代码语言:javascript
复制
 <xsl:number count="item" />

正确的代码应该是...

代码语言:javascript
复制
<xsl:variable name="phase-2-output">
  <xsl:apply-templates select="exslt:node-set($phase-1-output)" mode="phase-2" />
</xsl:variable>

代码语言:javascript
复制
 <xsl:number count="item[(FareClass!='G') and (FareClass!='Y')]" />
票数 1
EN

Stack Overflow用户

发布于 2012-10-17 18:03:11

代码语言:javascript
复制
<?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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12924600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档