我们假设你有下面的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分组可以与它一起使用来产生多个输出文件。但是,核心问题是我们可以在导出到新文件之前设置人数阈值吗?
答案 0 :(得分: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() < $n]/Person"/>
</People>
</exsl:document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>