2012-11-29 64 views
0

我是XSLT 1.0的初学者。我正在使用XSLT将XML转换为XML。 我想从收到的XML中获得前5个独特的Airline。XSLT获得前五个独特结果

源XML:

<Response> 
    <Flights> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>AB</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>CD</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>EF</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>EF</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>EF</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>EF</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
     <Flight> 
      <Segments> 
       <Segment> 
        <Airline>SD</Airline> 
       </Segment> 
      </Segments> 
     </Flight> 
    </Flights> 
    <OtherRecommens> 
     <RecommFlight> 
      <Airline>XY</Airline> 
     </RecommFlight> 
     <RecommFlight> 
      <Airline>ZZ</Airline> 
     </RecommFlight> 
     <RecommFlight> 
      <Airline>XY</Airline> 
     </RecommFlight> 
     <RecommFlight> 
      <Airline>AB</Airline> 
     </RecommFlight> 
    </OtherRecommens> 
</Response> 

XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="Response"> 
     <xsl:element name="Root"> 
      <xsl:variable name="Airlines" select="//Airline"/> 
      <xsl:for-each select="$Airlines"> 
       <xsl:if test="not(preceding::Airline[.=current()/text()])"> 
        <xsl:element name="SpecificAirline"> 
         <xsl:value-of select="text()"/> 
        </xsl:element> 
       </xsl:if> 
      </xsl:for-each> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

通过应用上面的XSLT我得到的以下输出:

输出:

<Root> 
    <SpecificAirline>AB</SpecificAirline> 
    <SpecificAirline>CD</SpecificAirline> 
    <SpecificAirline>EF</SpecificAirline> 
    <SpecificAirline>SD</SpecificAirline> 
    <SpecificAirline>XY</SpecificAirline> 
    <SpecificAirline>ZZ</SpecificAirline> 
</Root> 

按我的要求,我需要得到的只有第一五家航空公司

预期输出:

<Root> 
    <SpecificAirline>AB</SpecificAirline> 
    <SpecificAirline>CD</SpecificAirline> 
    <SpecificAirline>EF</SpecificAirline> 
    <SpecificAirline>SD</SpecificAirline> 
    <SpecificAirline>XY</SpecificAirline> 
</Root> 

请帮助。谢谢。

回答

1

我已经使用这里描述的分组:此处描述how to apply group by on xslt elements

和数组索引限制5 >= position()http://www.w3schools.com/xpath/xpath_functions.asp#context

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:output method="xml" indent="yes" /> 

    <xsl:key name="airlinetext" match="Airline" use="text()" /> 

    <xsl:template match="Response"> 
     <xsl:element name="Root"> 
      <xsl:apply-templates select="(//Airline[generate-id(.)=generate-id(key('airlinetext',text())[1])])[5&gt;=position()]"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="Airline"> 
       <xsl:element name="SpecificAirline"> 
        <xsl:value-of select="text()"/> 
       </xsl:element> 
    </xsl:template> 

</xsl:stylesheet>