XSLT找到最低价格

时间:2012-12-05 12:23:45

标签: xml xslt transform xslt-1.0 xslt-grouping

我是XSLT的初学者,用于将XML转换为XML。

我需要获得总和最低的Prices标记。

源XML:

<Result>
    <Fares>
        <Fare>
            <Prices>
                <Price type="adt" ticket="15"/>
                <Price type="chd" ticket="10"/>
                <Price type="inf" ticket="10"/>
            <Prices>
        </Fare>
        <Fare>
            <Prices>
                <Price type="adt" ticket="10"/>
                <Price type="chd" ticket="10"/>
                <Price type="inf" ticket="10"/>
            <Prices>
        </Fare>
        <Fare>
            <Prices>
                <Price type="adt" ticket="5"/>
                <Price type="chd" ticket="5"/>
                <Price type="inf" ticket="5"/>
            <Prices>
        </Fare>
        <Fare>
            <Prices>
                <Price type="adt" ticket="10"/>
                <Price type="chd" ticket="5"/>
                <Price type="inf" ticket="5"/>
            <Prices>
        </Fare>
    </Fares>
</Result>

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="Result">
        <xsl:element name="Lowest">
            <xsl:variable name="lowest" select="Fares/Fare/Prices[not(sum(Price/@ticket) &gt; //Fares/Fare/Prices[sum(Price/@ticket)])]"/>
            <xsl:copy-of select="$lowest"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

输出:

<Lowest>
    <Prices>
        <Price type="adt" ticket="15"/>
        <Price type="chd" ticket="10"/>
        <Price type="inf" ticket="10"/>
    <Prices/>
    </Prices>
</Lowest>

预期输出:

<Lowest>
    <Prices Total="15">
        <Price type="adt" ticket="5"/>
        <Price type="chd" ticket="5"/>
        <Price type="inf" ticket="5"/>
    <Prices>
</Lowest>

如上所示,输出应该具有Prices标记,其值最低也是属性。

请帮忙。

3 个答案:

答案 0 :(得分:2)

您可以按排序顺序排序并获取第一个:

<xsl:template match="Result">
  <Lowest>
    <xsl:for-each select="Fares/Fare/Prices">
      <xsl:sort select="sum(Price/@ticket)" data-type="number"/>
      <xsl:if test="position() = 1">
         <Prices Total="{sum(Price/@ticket)}">
           <xsl:copy-of select="node()"/>
         </Prices>
      </xsl:if>
    </xsl:for-each>
  </Lowest>
</xsl:template>

答案 1 :(得分:2)

您尚未关闭<Prices>代码!

但这应该可以解决问题:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" omit-xml-declaration="yes"/>
  <xsl:template match="/">
    <Lowest>
      <xsl:for-each select="/Result/Fares/Fare/Prices">
        <xsl:sort select="sum(./Price/@ticket)" data-type="number" order="ascending"/>
        <xsl:if test="position() = 1">
          <Prices>
            <xsl:attribute name="Total">
              <xsl:value-of select="sum(./Price/@ticket)"/>
            </xsl:attribute>
            <xsl:copy-of select="./Price"/>
          </Prices>
        </xsl:if>
      </xsl:for-each>
    </Lowest>
  </xsl:template>
</xsl:stylesheet>

答案 2 :(得分:1)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:for-each select="/*/*/Fare">
       <xsl:sort select="sum(Prices/Price/@ticket)" data-type="number"/>

       <xsl:if test="position()=1">
         <Lowest Total="{sum(Prices/Price/@ticket)}">
           <xsl:copy-of select="Prices"/>
         </Lowest>
       </xsl:if>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时(纠正了多个错误!):

<Result>
    <Fares>
        <Fare>
            <Prices>
                <Price type="adt" ticket="15"/>
                <Price type="chd" ticket="10"/>
                <Price type="inf" ticket="10"/>
            </Prices>
        </Fare>
        <Fare>
            <Prices>
                <Price type="adt" ticket="10"/>
                <Price type="chd" ticket="10"/>
                <Price type="inf" ticket="10"/>
            </Prices>
        </Fare>
        <Fare>
            <Prices>
                <Price type="adt" ticket="5"/>
                <Price type="chd" ticket="5"/>
                <Price type="inf" ticket="5"/>
            </Prices>
        </Fare>
        <Fare>
            <Prices>
                <Price type="adt" ticket="10"/>
                <Price type="chd" ticket="5"/>
                <Price type="inf" ticket="5"/>
            </Prices>
        </Fare>
    </Fares>
</Result>

生成想要的正确结果

<Lowest Total="15">
   <Prices>
      <Price type="adt" ticket="5"/>
      <Price type="chd" ticket="5"/>
      <Price type="inf" ticket="5"/>
   </Prices>
</Lowest>