2010-11-15 27 views
0

讓我們假設,您有下面的xml。目標是按FirstName進行分組並將Person導出到不同的xml文件中。每個輸出xml文件最多隻能包含X 不同的名字。XSLT:根據分組輸出到多個xml文件

下面是其中X = 3

XML輸入所需的變換的例子:

<People> 
    <Person>    
     <FirstName>John</FirstName>    
     <LastName>Doe</LastName> 
    </Person> 
    <Person>    
     <FirstName>Jack</FirstName>    
     <LastName>White</LastName> 
    </Person> 
    <Person>    
     <FirstName>Mark</FirstName>    
     <LastName>Wall</LastName> 
    </Person> 
    <Person>    
     <FirstName>John</FirstName>    
     <LastName>Ding</LastName> 
    </Person> 
    <Person>    
     <FirstName>Cyrus</FirstName>    
     <LastName>Ding</LastName> 
    </Person> 
    <Person>    
     <FirstName>Megan</FirstName>    
     <LastName>Boing</LastName> 
    </Person> 
</People>   

XML輸出1與3個不同的姓

<People> 
    <Person>    
     <FirstName>John</FirstName>    
     <LastName>Doe</LastName> 
    </Person> 
    <Person>    
     <FirstName>John</FirstName>    
     <LastName>Ding</LastName> 
    </Person> 
    <Person>    
     <FirstName>Jack</FirstName>    
     <LastName>White</LastName> 
    </Person> 
    <Person>    
     <FirstName>Mark</FirstName>    
     <LastName>Wall</LastName> 
    </Person> 
</People> 

XML輸出2與剩餘的2個名字

<People> 
    <Person>    
     <FirstName>Cyrus</FirstName>    
     <LastName>Ding</LastName> 
    </Person> 
    <Person>    
     <FirstName>Megan</FirstName>    
     <LastName>Boing</LastName> 
    </Person> 
</People> 

在我看來,muenchian分組可以與產生多個輸出文件一起使用。但是,核心問題是我們可以在輸出到新文件之前在哪個位置設置閾值?

回答

1

這裏是XSLT 2.0做的兩個步驟的一個例子:

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

    <xsl:param name="n" as="xs:integer" select="3"/> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="People"> 
    <xsl:variable name="groups" as="element(group)*"> 
     <xsl:for-each-group select="Person" group-by="FirstName"> 
     <group> 
      <xsl:copy-of select="current-group()"/> 
     </group> 
     </xsl:for-each-group> 
    </xsl:variable> 
    <xsl:for-each-group select="$groups" group-by="(position() - 1) idiv $n"> 
     <xsl:result-document href="group{position()}.xml"> 
     <People> 
      <xsl:copy-of select="current-group()"/> 
     </People> 
     </xsl:result-document> 
    </xsl:for-each-group> 
    </xsl:template> 

</xsl:stylesheet> 

我可能會嘗試將轉換爲XSLT 1.0和EXSLT以後。

[編輯] 這裏是翻譯成XSLT 1.0和EXSLT嘗試:

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

    <xsl:param name="n" select="3"/> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:key name="person-by-firstname" 
      match="Person" 
      use="FirstName"/> 

    <xsl:template match="People"> 
    <xsl:variable name="groups"> 
     <xsl:for-each select="Person[generate-id() = generate-id(key('person-by-firstname', FirstName)[1])]"> 
     <group> 
      <xsl:copy-of select="key('person-by-firstname', FirstName)"/> 
     </group> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:for-each select="exsl:node-set($groups)/group[(position() - 1) mod $n = 0]"> 
     <exsl:document href="groupTest{position()}.xml"> 
     <People> 
      <xsl:copy-of select="Person | following-sibling::group[position() &lt; $n]/Person"/> 
     </People> 
     </exsl:document> 
    </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 
+0

+1很好的回答。 – 2010-11-15 21:38:33

+0

很好的答案 – Daniel 2010-11-16 15:17:53

相關問題