0

假设,您有下面的 xml。目标是按 FirstName 分组并将 Person 导出到不同的 xml 文件中。每个输出 xml 文件最多只能包含 X个不同的FirstName。

下面是 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 个不同的 FirstName

<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 剩余的 FirstName

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

在我看来,muenchian 分组可以与 一起使用来生成多个输出文件。但是,核心问题是在导出到新文件之前,我们可以在哪里设置人数阈值?

4

1 回答 1

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>
于 2010-11-15T09:50:40.290 回答