2010-11-12 8 views
5

Mam plik XSLT, aby przekształcić duże ilości danych. Chciałbym dodać funkcjonalność "split", zarówno w postaci łańcucha XSLT, jak i bieżącego XSLT, który może tworzyć wiele plików wyjściowych, aby ograniczyć rozmiar plików poniżej pewnego progu. Załóżmy, że wejście jest XML jak poniżej:Pliki wyjściowe podzielonego pliku XSLT - grupa muenchian

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

Plik XSLT jest poniżej za pomocą muenchian zgrupowanie.

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

Jednak chciałbym, jako wynik, kilka plików, jak poniżej, zamiast dużego. W tym przykładzie ustawiłem tylko jedną nazwę dla pliku ... ale powinien to być parametr.

pliku wyjściowego dla pierwszej osobie:

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

plik wyjściowy dla drugiej osoby:

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

Co byłoby korzystne i najbardziej elegancki podejście przy użyciu XSLT 1.0? Czy istnieje sposób wywołania powiązanego XSLT w XSLT, aby podzielić pliki wyjściowe?

Pozdrawiam.

+0

Dobre pytanie, +1. Zobacz moją odpowiedź na kilka sposobów, aby to zrobić. –

Odpowiedz

6

Czy istnieje sposób, aby wywołać przykuty XSLT w XSLT, tak aby podzielić pliki wyjściowe ?

Kilka sposobów:

  1. można napisać funkcję przedłużacza do tego zrobić - sprawdzić dokumentację procesora XSLT.

  2. Użyj elementu <exsl:document> przedłużacz z EXSLT, w przypadku, gdy jest obsługiwana przez procesor XSLT

  3. Korzystanie element <saxon:output> przedłużenie jeśli masz Saxon 6.x

  4. W pętla z twojego języka programowania wywołuje osobną transformację, przekazując jej jako parametrowi nazwę osoby, dla której uzyskuje się wyniki.

Oto przykłady kodu do 2. i 3.powyżej:

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

kiedy ta transformacja jest stosowane na poniższym dokumencie XML:

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

trzy pliki: c:\xml\doc1, c:\xml\doc2 i c:\xml\doc3 są tworzone z poszukiwanych treści .

Ten sam przykład przy użyciu <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

Myślę, że exsl: dokument wydaje się być najlepszym pomysłem. Czy masz jakiś wgląd w to, jak by to działało w danym przykładzie? – Daniel

+0

@Daniel: Dodałem dwa przykłady kodu: dla '' i dla '' –

+0

@Dimitre. Dzięki i czy masz trochę wglądu w to, w jaki sposób twoje rozwiązanie może być połączone z grupowym XSLT w pytaniu? – Daniel