2011-03-18 7 views
2

모든 ShippingPoint가 먼저 정렬 된 다음 첫 번째 ShippingPoint에 따라 Cargos가 첫 번째 ShippingPoint에 따라 마지막으로 TransportPoint에 따라 예제 XML을 정렬해야합니다 뱃짐. 그래서 기본적으로 나는 그들이 시작되기로되어있는 날짜에 따라 모든 수송선을 분류하려고 시도하고 있습니다.XML을 재귀 적으로 정렬 - 내부 노드 만 정렬합니다.

이제 Cargos 및 ShippingPoints 만 예상대로 정렬된다는 점을 제외하고는 XSL 재귀를 사용하여 솔루션을 찾았습니다. 가장 외부의 전송 노드는 아닙니다. 내가 여기서 뭘 잘못하고 있는지 궁금해. MSXML (VS2008)과 Saxon 파서는 똑같은 결과를줍니다.

예제 XML 코드 :

<?xml version="1.0" encoding="utf-8"?> 
<Transports> 
    <Transport ID="1893"> 
     <Cargos> 
      <Cargo ID="1532" > 
       <ShippingPoints> 
        <ShippingPoint ID="1600" ArrivesOn="2011-04-07T12:00:00" /> 
        <ShippingPoint ID="1601" ArrivesOn="2011-04-08T12:00:00" /> 
       </ShippingPoints> 
      </Cargo> 
      <Cargo ID="1532"> 
       <ShippingPoints> 
        <ShippingPoint ID="1601" ArrivesOn="2011-03-08T12:00:00" /> 
        <ShippingPoint ID="1600" ArrivesOn="2011-02-07T12:00:00" /> 
       </ShippingPoints> 
      </Cargo> 
     </Cargos> 
    </Transport> 

    <Transport ID="1891" > 
     <Cargos> 
      <Cargo ID="1529" > 
       <ShippingPoints> 
        <ShippingPoint ID="1594" ArrivesOn="2011-04-14T12:00:00" /> 
        <ShippingPoint ID="1595" ArrivesOn="2011-04-04T13:00:00" /> 
       </ShippingPoints> 
      </Cargo> 
      <Cargo ID="1530" > 
       <ShippingPoints> 
        <ShippingPoint ID="1597" ArrivesOn="2011-04-09T18:00:00" /> 
        <ShippingPoint ID="1596" ArrivesOn="2011-04-04T12:00:00" /> 
       </ShippingPoints> 
      </Cargo> 
     </Cargos> 
    </Transport> 

    <Transport ID="1892"> 
     <Description/> 
     <Cargos> 
      <Cargo ID="1531" > 
       <ShippingPoints> 
        <ShippingPoint ID="1599" ArrivesOn="2011-04-06T18:00:00" /> 
        <ShippingPoint ID="1598" ArrivesOn="2011-04-05T12:00:00" /> 
       </ShippingPoints> 
      </Cargo> 
      <Cargo ID="1531" > 
       <ShippingPoints> 
        <ShippingPoint ID="1599" ArrivesOn="2011-04-02T18:00:00" /> 
        <ShippingPoint ID="1598" ArrivesOn="2011-04-03T12:00:00" /> 
       </ShippingPoints> 
      </Cargo> 
     </Cargos> 
    </Transport> 
</Transports> 

XSLT 코드 :

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xsl:output method="xml" version="1.0" encoding="UTF-8" /> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ShippingPoints"> 
     <xsl:copy> 
      <xsl:apply-templates select="ShippingPoint"> 
       <xsl:sort select="@ArrivesOn" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Cargos"> 
     <xsl:copy> 
      <xsl:apply-templates select="Cargo"> 
       <xsl:sort select="ShippingPoints/ShippingPoint[1]/@ArrivesOn" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Transports"> 
     <xsl:copy> 
      <xsl:apply-templates select="Transport"> 
       <xsl:sort select="Cargos/Cargo[1]/ShippingPoints/ShippingPoint[1]/@ArrivesOn"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

답변

3

내가 이것을 이해하지 못하면 최소한 @ArrivesOn 명의 자손을 찾고 있습니다. 가장 짧은 스타일 :

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates select="node()"> 
       <xsl:sort select="min(.//@ArrivesOn/xs:dateTime(.))"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

출력 :

<Transports> 
    <Transport ID="1893"> 
     <Cargos> 
      <Cargo ID="1532"> 
       <ShippingPoints> 
        <ShippingPoint ID="1600" ArrivesOn="2011-02-07T12:00:00"/> 
        <ShippingPoint ID="1601" ArrivesOn="2011-03-08T12:00:00"/> 
       </ShippingPoints> 
      </Cargo> 
      <Cargo ID="1532"> 
       <ShippingPoints> 
        <ShippingPoint ID="1600" ArrivesOn="2011-04-07T12:00:00"/> 
        <ShippingPoint ID="1601" ArrivesOn="2011-04-08T12:00:00"/> 
       </ShippingPoints> 
      </Cargo> 
     </Cargos> 
    </Transport> 
    <Transport ID="1892"> 
     <Description/> 
     <Cargos> 
      <Cargo ID="1531"> 
       <ShippingPoints> 
        <ShippingPoint ID="1599" ArrivesOn="2011-04-02T18:00:00"/> 
        <ShippingPoint ID="1598" ArrivesOn="2011-04-03T12:00:00"/> 
       </ShippingPoints> 
      </Cargo> 
      <Cargo ID="1531"> 
       <ShippingPoints> 
        <ShippingPoint ID="1598" ArrivesOn="2011-04-05T12:00:00"/> 
        <ShippingPoint ID="1599" ArrivesOn="2011-04-06T18:00:00"/> 
       </ShippingPoints> 
      </Cargo> 
     </Cargos> 
    </Transport> 
    <Transport ID="1891"> 
     <Cargos> 
      <Cargo ID="1530"> 
       <ShippingPoints> 
        <ShippingPoint ID="1596" ArrivesOn="2011-04-04T12:00:00"/> 
        <ShippingPoint ID="1597" ArrivesOn="2011-04-09T18:00:00"/> 
       </ShippingPoints> 
      </Cargo> 
      <Cargo ID="1529"> 
       <ShippingPoints> 
        <ShippingPoint ID="1595" ArrivesOn="2011-04-04T13:00:00"/> 
        <ShippingPoint ID="1594" ArrivesOn="2011-04-14T12:00:00"/> 
       </ShippingPoints> 
      </Cargo> 
     </Cargos> 
    </Transport> 
</Transports> 
+0

그 트릭을 했어 - 간단하고 깨끗한. 감사! – dawidw

+0

@ dawidw : 천만에. –

0

당신은 단계 변환에 의해 단계는 다음 다음 XSLT에서와 같이 일시적인 결과를 저장하는 모드와 변수를 사용해야합니다 2.0 예 :

<?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" version="1.0" indent="yes" encoding="UTF-8" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
     <xsl:variable name="t1"> 
     <xsl:apply-templates mode="step1"/> 
     </xsl:variable> 
     <xsl:variable name="t2"> 
     <xsl:apply-templates select="$t1/node()" mode="step2"/> 
     </xsl:variable> 
     <xsl:apply-templates select="$t2/node()"/> 
    </xsl:template> 

    <xsl:template match="@*|node()" mode="#all"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*, node()" mode="#current"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="ShippingPoints" mode="step1"> 
     <xsl:copy> 
      <xsl:apply-templates select="ShippingPoint"> 
       <xsl:sort select="@ArrivesOn" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Cargos" mode="step2"> 
     <xsl:copy> 
      <xsl:apply-templates select="Cargo"> 
       <xsl:sort select="ShippingPoints/ShippingPoint[1]/@ArrivesOn" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Transports"> 
     <xsl:copy> 
      <xsl:apply-templates select="Transport"> 
       <xsl:sort select="Cargos/Cargo[1]/ShippingPoints/ShippingPoint[1]/@ArrivesOn"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

나는 XSLT 2.0 proce로 원하는 것을 수행한다고 생각한다. 소서.

+0

감사 @martin. 그것은 여기서도 효과가 있었지만, 단계적으로 변환을 수행 할 필요가 없기 때문에 @alejandro가 제안한 것을 찾으러갔습니다. – dawidw