2012-12-05 64 views
2

我是XSLT的初学者,用于将XML转换为XML。XSLT找到最低价格

我需要得到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> 

例pected输出:

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

如上所示输出应具有Prices标签具有最低值作为属性也。

请帮忙。

+0

嗨,你可以分享你的XSLT代码..?你有什么尝试? –

+0

您确定您所展示的XSLT实际上给出了您所说的输出吗?对我来说,使用撒克逊6.5.5,它会给出不同的输出:它输出所有四个元素及其后代。 – LarsH

+0

@LarsH - 我使用java将XML转换为XML,并且引擎是JAXP(默认值为1)。 –

回答

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文档应用(有几个malformities纠正!!!):

<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> 
+0

Dimitre,OP想要为''元素添加一个'Total'属性。顺便说一下,增加一个解释为什么OP的原始XPath表达式不起作用会很有帮助,所以我们必须使用for-each来进行排序。在XSLT 1.0中与sum()'的限制有什么关系? – LarsH

+0

@LarsH,谢谢,现在更新。 –

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

我觉得你的意思是'{sum(Price/@ ticket)}'。 – LarsH

+0

@Martin - 我试过了,但是得到了第一个'价格'标签,其值为'Total' 35. –

+1

Lars是对的,我用错了'sum'表达式,我会纠正它。 –

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> 
+0

使用这个解决方案,我得到了'。 –

+0

那你在开发什么呢?我使用了Visual Studio 2010 XSLT调试器并得到了正确的结果... –

+0

我正在使用http://www.purplegene.com/static/transform.html –