2017-09-14 3 views
0

Ich muss eine XSLT-Datei verwenden, um ein XML in CSV umzuwandeln. Das ist einfach genug.XSLT einen eindeutigen Knoten zählen

Ich muss auch verschiedene Werte von einem Knoten zählen und sie in jede Zeile einfügen. Das weiß ich nicht, was ich machen soll.

Der Knoten, den ich zählen muss, können Sie im folgenden Beispiel sehen. Es heißt < Id>.

Ich möchte grundsätzlich alle IDs, die eindeutig sind, zählen und das Ergebnis in jeden Bestellposten einfügen.

Seit meinem Beispiel haben zwei < id> Knoten mit dem Wert 1 und ein < id> Knoten mit dem Wert 4, wären das Ergebnis 2.

Vielen Dank im Voraus, überhaupt für jede Hilfe.

XML:

<?xml version="1.0" encoding="utf-8"?> 
<Picked xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <OrderLines> 
     <OrderLine> 
      <OrderId>1345 
      </OrderId> 
      <Missions> 
       <Mission> 
        <ContainerIds> 
         <Container> 
          <Id>1 
          </Id> 
         </Container> 
        </ContainerIds> 
       </Mission> 
      </Missions> 
     </OrderLine> 
     <OrderLine> 
      <OrderId>13456 
      </OrderId> 
      <Missions> 
       <Mission> 
        <ContainerIds> 
         <Container> 
          <Id>1 
          </Id> 
         </Container> 
        </ContainerIds> 
       </Mission> 
      </Missions> 
     </OrderLine> 
     <OrderLine> 
      <OrderId>134567 
      </OrderId> 
      <Missions> 
       <Mission> 
        <ContainerIds> 
         <Container> 
          <Id>4 
          </Id> 
         </Container> 
        </ContainerIds> 
       </Mission> 
      </Missions> 
     </OrderLine> 
    </OrderLines> 
</Picked> 

Wunschergebnis:

Orderid;Id 
    1345;2 
    13456;2 
    134567;2 

XSLT so weit:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="text" encoding="UTF-8"/> 
    <xsl:template match='/'> 

    <xsl:text>Orderid;Id</xsl:text> 
    <xsl:text>&#10;</xsl:text> 

    <xsl:for-each select="/Picked/OrderLines/OrderLine"> 
     <xsl:value-of select="OrderId"/> 
     <xsl:text>;</xsl:text> 
     <xsl:value-of select="Missions/Mission/ContainerIds/Container/Id"/>       
     <xsl:if test="position()!=last()"> 
     <xsl:text>&#10;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Mein Ergebnis bisher:

Orderid;Id 
    1345;1 
    13456;1 
    134567;4 
+0

Welche XSLT-Prozessor werden Sie verwenden? –

+0

Ich werde XSLT 1.0 verwenden – stianzz

+0

Aber welcher spezielle Prozessor? Einige unterstützen eine 'distinct()' Erweiterungsfunktion. –

Antwort

1

In XSLT-1.0 gibt es mehrere Möglichkeiten, unterschiedliche Werte zu erhalten. Sie sind in this good SO answer aufgezählt.

Ich habe den Ansatz von Nick Grealy, die Verwendung von generate-id() zu vermeiden, und zählte die resultierenden Knoten.

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="text" encoding="UTF-8"/> 

    <xsl:template match='/'> 
     <xsl:text>Orderid;Id</xsl:text> 
     <xsl:text>&#10;</xsl:text> 
     <xsl:for-each select="/Picked/OrderLines/OrderLine"> 
      <xsl:value-of select="OrderId"/> 
      <xsl:text>;</xsl:text> 
      <xsl:value-of select="count(//Id[not(.=preceding::*)])"/> <!-- count above all Id's in document --> 
      <xsl:if test="position()!=last()"> 
       <xsl:text>&#10;</xsl:text> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Ausgang:

Orderid;Id 
1345;2 
13456;2 
134567;2 
+0

Dieses Prädikat '[generate-id() = Schlüssel ('unique',.)]' Sieht falsch aus ... –

+0

@MichaelKay: Danke. Ich habe die Zeile komplett entfernt - unnötiger Rest der vorherigen Version. – zx485

+0

"* Vermeidung der Verwendung von generate-id() *" Warum ist das eine gute Sache? Lesen Sie hier, warum es nicht ist: http://www.jenitennison.com/xslt/grouping/muenchian.html –

2

XSLT 3.0-Lösung zum Vergleich:

<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    expand-text="yes"> 

    <xsl:output method="text" encoding="UTF-8"/> 

    <xsl:template match='/'> 
     <xsl:text>Orderid;Id&#10;</xsl:text> 
     <xsl:for-each select="/Picked/OrderLines/OrderLine"> 
      <xsl:text>{OrderId};{count(distinct-values(//Id))}&#10;</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet>