2012-05-11 3 views
2

J'essaie de créer une feuille de style xslt pour transformer xml. J'ai étudié la méthode muenchienne mais je ne suis pas familier avec la façon dont tout cela fonctionne. J'ai des difficultés parce que chaque ManifestNo peut avoir n'importe quel nombre de SequenceNo. J'essaye de grouper l'ordre plat dans le xml source à un ordre dans le xml de destination avec des détails d'arrêt imbriqués.Feuille de style XSLT pour transformer xml

<Orders> 
    <Order> 
    <ManifestNo>283749</ManifestNo> 
    <Warehouse>35</Warehouse> 
    <SequenceNo>1</SequenceNo> 
    <CustomerOrderNo>3524771-01</CustomerOrderNo> 
    <Weight>180</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283749</ManifestNo> 
    <Warehouse>35</Warehouse> 
    <SequenceNo>1</SequenceNo> 
    <CustomerOrderNo>3524771-02</CustomerOrderNo> 
    <Weight>250</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283749</ManifestNo> 
    <Warehouse>35</Warehouse> 
    <SequenceNo>2</SequenceNo> 
    <CustomerOrderNo>3524728-01</CustomerOrderNo> 
    <Weight>25</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283750</ManifestNo> 
    <Warehouse>50</Warehouse> 
    <SequenceNo>1</SequenceNo> 
    <CustomerOrderNo>5464565-01</CustomerOrderNo> 
    <Weight>150</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283750</ManifestNo> 
    <Warehouse>50</Warehouse> 
    <SequenceNo>2</SequenceNo> 
    <CustomerOrderNo>5874565-02</CustomerOrderNo> 
    <Weight>125</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283750</ManifestNo> 
    <Warehouse>50</Warehouse> 
    <SequenceNo>2</SequenceNo> 
    <CustomerOrderNo>3524888-01</CustomerOrderNo> 
    <Weight>95</Weight> 
    </Order> 
</Orders> 

à

<Orders> 
    <Order> 
     <ManifestNo>283749</ManifestNo> 
     <Warehouse>35</Warehouse> 
     <Stop> 
      <SequenceNo>1</SequenceNo> 
      <Freight> 
       <CustomerOrderNo>3524771-01</CustomerOrderNo> 
       <Weight>180</Weight> 
      </Freight> 
      <Freight> 
       <CustomerOrderNo>3524771-02</CustomerOrderNo> 
       <Weight>250</Weight> 
      </Freight> 
     </Stop> 
     <Stop> 
      <SequenceNo>2</SequenceNo> 
      <Freight> 
       <CustomerOrderNo>3524728-01</CustomerOrderNo> 
       <Weight>25</Weight> 
      </Freight> 
      <Freight> 
       <CustomerOrderNo>3524771-02</CustomerOrderNo> 
       <Weight>250</Weight> 
      </Freight> 
     </Stop> 
     </Order> 
     <Order> 
     <ManifestNo>283750</ManifestNo> 
     <Warehouse>50</Warehouse> 
     <Stop> 
      <SequenceNo>1</SequenceNo> 
      <Freight> 
       <CustomerOrderNo>5464565-01</CustomerOrderNo> 
       <Weight>150</Weight> 
      </Freight> 
     </Stop> 
     <Stop> 
      <SequenceNo>2</SequenceNo> 
      <Freight> 
       <CustomerOrderNo>5874565-02</CustomerOrderNo> 
       <Weight>125</Weight> 
      </Freight> 
      <Freight> 
       <CustomerOrderNo>3524888-0</CustomerOrderNo> 
       <Weight>95</Weight> 
      </Freight> 
     </Stop> 
     </Order> 
    </Orders> 

Répondre

1

I. Cette transformation XSLT 1.0:

<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:key name="kOrderByNum" match="Order" 
     use="ManifestNo"/> 

    <xsl:key name="kSeqInOrder" match="SequenceNo" 
     use="concat(../ManifestNo, '+', .)"/> 

    <xsl:key name="kSeqByOrderNo" match="SequenceNo" 
     use="../ManifestNo"/> 

    <xsl:template match="Order"/> 
    <xsl:template match="SequenceNo"/> 

    <xsl:template match="/*"> 
    <Orders> 
     <xsl:apply-templates/> 
    </Orders> 
    </xsl:template> 

    <xsl:template match= 
     "Order 
     [generate-id() 
     = 
      generate-id(key('kOrderByNum', ManifestNo)[1]) 
      ]"> 
     <Order> 
     <xsl:copy-of select="ManifestNo|Warehouse"/> 

     <xsl:apply-templates select= 
     "key('kSeqByOrderNo', ManifestNo) 
      [generate-id() 
      = 
      generate-id(key('kSeqInOrder', 
          concat(../ManifestNo, '+', .) 
          )[1] 
        ) 
      ] 
     "/> 
     </Order> 
    </xsl:template> 

    <xsl:template match="SequenceNo[true()]"> 
     <Stop> 
     <xsl:copy-of select="."/> 
     <xsl:apply-templates mode="inGroup" select= 
     "key('kSeqInOrder', 
       concat(../ManifestNo, '+', .))"/> 
     </Stop> 
    </xsl:template> 

    <xsl:template match="SequenceNo" mode="inGroup"> 
     <Freight> 
     <xsl:copy-of select="../CustomerOrderNo|../Weight"/> 
     </Freight> 
    </xsl:template> 
    </xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML fourni:

<Orders> 
    <Order> 
    <ManifestNo>283749</ManifestNo> 
    <Warehouse>35</Warehouse> 
    <SequenceNo>1</SequenceNo> 
    <CustomerOrderNo>3524771-01</CustomerOrderNo> 
    <Weight>180</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283749</ManifestNo> 
    <Warehouse>35</Warehouse> 
    <SequenceNo>1</SequenceNo> 
    <CustomerOrderNo>3524771-02</CustomerOrderNo> 
    <Weight>250</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283749</ManifestNo> 
    <Warehouse>35</Warehouse> 
    <SequenceNo>2</SequenceNo> 
    <CustomerOrderNo>3524728-01</CustomerOrderNo> 
    <Weight>25</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283750</ManifestNo> 
    <Warehouse>50</Warehouse> 
    <SequenceNo>1</SequenceNo> 
    <CustomerOrderNo>5464565-01</CustomerOrderNo> 
    <Weight>150</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283750</ManifestNo> 
    <Warehouse>50</Warehouse> 
    <SequenceNo>2</SequenceNo> 
    <CustomerOrderNo>5874565-02</CustomerOrderNo> 
    <Weight>125</Weight> 
    </Order> 
    <Order> 
    <ManifestNo>283750</ManifestNo> 
    <Warehouse>50</Warehouse> 
    <SequenceNo>2</SequenceNo> 
    <CustomerOrderNo>3524888-01</CustomerOrderNo> 
    <Weight>95</Weight> 
    </Order> 
</Orders> 

produit le résultat souhaité, correct:

<Orders> 
    <Order> 
     <ManifestNo>283749</ManifestNo> 
     <Warehouse>35</Warehouse> 
     <Stop> 
     <SequenceNo>1</SequenceNo> 
     <Freight> 
      <CustomerOrderNo>3524771-01</CustomerOrderNo> 
      <Weight>180</Weight> 
     </Freight> 
     <Freight> 
      <CustomerOrderNo>3524771-02</CustomerOrderNo> 
      <Weight>250</Weight> 
     </Freight> 
     </Stop> 
     <Stop> 
     <SequenceNo>2</SequenceNo> 
     <Freight> 
      <CustomerOrderNo>3524728-01</CustomerOrderNo> 
      <Weight>25</Weight> 
     </Freight> 
     </Stop> 
    </Order> 
    <Order> 
     <ManifestNo>283750</ManifestNo> 
     <Warehouse>50</Warehouse> 
     <Stop> 
     <SequenceNo>1</SequenceNo> 
     <Freight> 
      <CustomerOrderNo>5464565-01</CustomerOrderNo> 
      <Weight>150</Weight> 
     </Freight> 
     </Stop> 
     <Stop> 
     <SequenceNo>2</SequenceNo> 
     <Freight> 
      <CustomerOrderNo>5874565-02</CustomerOrderNo> 
      <Weight>125</Weight> 
     </Freight> 
     <Freight> 
      <CustomerOrderNo>3524888-01</CustomerOrderNo> 
      <Weight>95</Weight> 
     </Freight> 
     </Stop> 
    </Order> 
</Orders> 

II. XSLT 2.0 Solution:

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

<xsl:key name="kSeqByOrderNo" match="SequenceNo" 
     use="../ManifestNo"/> 

<xsl:template match="/*"> 
    <Orders> 
    <xsl:for-each-group select="Order" group-by="ManifestNo"> 
     <Order> 
     <xsl:copy-of select="ManifestNo|Warehouse"/> 

     <xsl:for-each-group select="key('kSeqByOrderNo', ManifestNo)" 
     group-by="."> 
     <xsl:copy-of select="."/> 
     <Stop> 
      <xsl:apply-templates select="current-group()"/> 
     </Stop> 
     </xsl:for-each-group> 
     </Order> 
    </xsl:for-each-group> 
    </Orders> 
</xsl:template> 

<xsl:template match="SequenceNo"> 
    <Freight> 
    <xsl:copy-of select="../CustomerOrderNo|../Weight"/> 
    </Freight> 
</xsl:template> 
</xsl:stylesheet> 
+0

Fonctionne parfaitement! Merci beaucoup! – user1390240

+0

@ user1390240: De rien. –

Questions connexes