2012-12-05 4 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가 실제로 말하는 출력을 제공합니까? 나를 위해 Saxon 6.5.5를 사용하면 다른 출력을 얻을 수 있습니다. 네 개의 ''요소와 자손을 모두 출력합니다. – LarsH

+0

@LarsH - XML을 XML로 변환하기 위해 java를 사용하고 있으며 엔진은 JAXP (기본값)입니다. –

답변

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' 속성을 추가하려고합니다. BTW, OP의 원래 XPath 표현식이 작동하지 않는 이유에 대한 설명을 추가하는 것이 도움이 될 것이므로 for-each를 sort와 함께 사용해야합니다. XSLT 1.0에서'sum()'의 한계와 관련이 있습니까? – LarsH

+0

@LarsH, 감사합니다. 지금 업데이트되었습니다. –

2

당신은 정렬하고 정렬 순서의 첫 번째 항목인지 하나를 수행 할 수 있습니다 당신은 당신의 <Prices> 태그를 폐쇄하지 않는

<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

@ Martins - 나는 그것을 시도했지만'Total'의 값을 가진 첫 번째'Prices' 태그를 얻었습니다. 35. –

+1

Lars가 맞습니다. 잘못된'sum' 식을 사용했습니다. –

2

을!

하지만이 트릭을 수행해야합니다

<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 –