XSLT: вывод в несколько XML-файлов на основе группировки - PullRequest
0 голосов
/ 15 ноября 2010

Предположим, у вас есть 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 с тремя разными именами 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 с оставшимися двумя именами FirstName

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

Мне кажется, что группировка muenchian может использоваться вместе с для создания нескольких выходных файлов.Тем не менее, основной вопрос заключается в том, где мы можем установить пороговое значение числа людей перед экспортом в новый файл?

1 Ответ

1 голос
/ 15 ноября 2010

Вот пример выполнения этого в два этапа с 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>
...