2010-11-12 12 views
5

Ich habe eine XSLT-Datei, um große Datenmengen zu transformieren. Ich möchte eine "Split" -Funktion hinzufügen, entweder als verkettete XSLT oder innerhalb der aktuellen XSLT, die mehrere Ausgabedateien erstellen kann, um die Größe der Dateien unter einem bestimmten Schwellenwert zu begrenzen. Nehmen wir an, dass die Eingabe von XML als unten:XSLT geteilte Ausgabedateien - Muenchsche Gruppierung

<People> 
<Person>    
<name>John</name>    
<date>June12</date>    
<workTime taskID="1">34</workTime>    
<workTime taskID="2">12</workTime>    
</Person>    
<Person>    
<name>John</name>    
<date>June13</date>    
<workTime taskID="1">21</workTime>    
<workTime taskID="2">11</workTime>    
</Person> 
<Person>    
<name>Jack</name>    
<date>June19</date>    
<workTime taskID="1">20</workTime>    
<workTime taskID="2">30</workTime>    
</Person>  
</People> 

Die XSLT-Datei ist als Muench-Gruppierung unten.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:key name="PersonTasks" match="workTime" use="concat(@taskID, ../name)"/> 
<xsl:template match="/"> 
    <People> 
    <xsl:apply-templates select="//workTime[generate-id() = generate-id(key('PersonTasks',concat(@taskID, ../name))[1])]"/> 
    </People> 
</xsl:template> 

<xsl:template match="workTime"> 
    <xsl:variable name="taskID"> 
     <xsl:value-of select="@taskID"/> 
    </xsl:variable> 
    <xsl:variable name="name"> 
     <xsl:value-of select="../name"/> 
    </xsl:variable> 
    <Person> 
     <name> 
      <xsl:value-of select="$name"/> 
     </name> 
     <taskID> 
      <xsl:value-of select="$taskID"/> 
     </taskID> 
     <xsl:for-each select="//workTime[../name = $name][@taskID = $taskID]"> 
      <workTime> 
       <date> 
        <xsl:value-of select="../date"/> 
       </date> 
       <time> 
        <xsl:value-of select="."/> 
       </time> 
      </workTime> 
     </xsl:for-each> 
    </Person> 
</xsl:template> 
</xsl:stylesheet> 

Allerdings möchte ich, als eine Ausgabe, mehrere Dateien wie unten statt einer großen. Für dieses Beispiel habe ich nur einen Namen pro Datei angegeben..aber das sollte ein Parameter sein.

Ausgabedatei für die erste Person:

<People> 
    <Person> 
     <name>John</name> 
     <taskID>1</taskID> 
     <workTime> 
     <date>June12</date> 
     <time>34</time> 
     </workTime> 
     <workTime> 
     <date>June13</date> 
     <time>21</time> 
     </workTime> 
    </Person> 
    <Person> 
     <name>John</name> 
     <taskID>2</taskID> 
     <workTime> 
     <date>June12</date> 
     <time>12</time> 
     </workTime> 
     <workTime> 
     <date>June13</date> 
     <time>11</time> 
     </workTime> 
    </Person> 
</People> 

Ausgabedatei für die zweite Person:

<People> 
    <Person> 
     <name>Jack</name> 
     <taskID>1</taskID> 
     <workTime> 
     <date>June19</date> 
     <time>20</time> 
     </workTime> 
    </Person> 
    <Person> 
     <name>Jack</name> 
     <taskID>2</taskID> 
     <workTime> 
     <date>June19</date> 
     <time>30</time> 
     </workTime> 
    </Person> 
</People> 

Was wäre der bevorzugte und eleganteste Ansatz mit Hilfe von XSLT 1.0? Gibt es eine Möglichkeit, eine verkettete XSLT innerhalb der XSLT aufzurufen, um die Ausgabedateien zu teilen?

Prost.

+0

Gute Frage, +1. Sehen Sie meine Antwort für eine Reihe von Möglichkeiten, dies zu tun. –

Antwort

6

Gibt es eine Möglichkeit, eine verkettete XSLT im XSLT zu nennen, um die Ausgabedateien aufgeteilt?

ein paar Möglichkeiten:

  1. Sie könnten eine Erweiterungsfunktion schreiben diese zu tun - in der Dokumentation Ihres XSLT-Prozessor.

  2. Verwenden Sie das <exsl:document> Verlängerungselement von EXSLT, falls dies von Ihrem XSLT-Prozessor unterstützt wird

  3. Verwenden Sie das <saxon:output> Verlängerungselement wenn Sie Saxon 6.x

  4. haben Eine Schleife aus Ihrer Programmiersprache ruft eine separate Umwandlung auf und übergibt ihr als Parameter den Namen der Person, für die Ergebnisse erzeugt werden sollen.

Hier sind Codebeispiele für 2. und 3.oben:

Mit <saxon:output>:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:saxon="http://icl.com/saxon" 
    extension-element-prefixes="saxon" > 

<xsl:template match="/"> 
    <xsl:for-each select="/*/*[not(. > 3)]"> 
    <saxon:output href="c:\xml\doc{.}"> 
    <xsl:copy-of select="."/> 
    </saxon:output> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

wenn diese Transformation auf das folgende XML-Dokument angewendet wird:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

drei Dateien: c:\xml\doc1, c:\xml\doc2 und c:\xml\doc3 erstellt werden, mit dem gesuchten Inhalt .

Das gleiche Beispiel mit <exslt:document>:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
    extension-element-prefixes="saxon" > 

<xsl:template match="/"> 
    <xsl:for-each select="/*/*[not(. > 3)]"> 
    <ext:document href="c:\xml\doc{.}"> 
    <xsl:copy-of select="."/> 
    </ext:document> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
+0

Ich denke exsl: Dokument scheint die beste Idee zu sein. Hast du einen Einblick, wie es für das jeweilige Beispiel funktionieren würde? – Daniel

+0

@Daniel: Ich habe zwei Codebeispiele hinzugefügt: für '' und für '' –

+0

@Dimitre. Vielen Dank und haben Sie einen Einblick, wie Ihre Lösung mit der Gruppierung XSLT in der Frage umgesetzt werden kann? – Daniel

Verwandte Themen