XSLT 转换以按重复元素拆分文件

XSLT Transform to split a file by repeated elements

我有一个 xml 文件,格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<Feed xmlns="http://www.somecompany.com/xs/PRR/SomeFeed/14.7" encryptionKeyID="ENCRYPTION-KEY-ID-2020-05-01T18:00:17.324Z">
   <Interaction>
      <EncryptedEmailAddress></EncryptedEmailAddress>
      <UserID></UserID>
      <UserName></UserName>
      <TransactionDate></TransactionDate>
      <Locale></Locale>
      <DeploymentZone></DeploymentZone>
      <Products>
         <Product>
            <ExternalId></ExternalId>
            <Name></Name>
            <Price></Price>
            <ImageUrl></ImageUrl>
         </Product>
         <Product>
            <ExternalId></ExternalId>
            <Name></Name>
            <Price></Price>
            <ImageUrl></ImageUrl>
         </Product>
      </Products>
   </Interaction>
   <Interaction>
      <EncryptedEmailAddress></EncryptedEmailAddress>
      <UserID></UserID>
      <UserName></UserName>
      <TransactionDate></TransactionDate>
      <Locale></Locale>
      <DeploymentZone></DeploymentZone>
      <Products>
         <Product>
            <ExternalId></ExternalId>
            <Name></Name>
            <Price>37</Price>
            <ImageUrl></ImageUrl>
         </Product>
      </Products>
   </Interaction>
</Feed>

此供稿可以有数百万次互动。我想创建一个 xsl 转换以一次使用 9000 次交互来拆分文件。我需要在每个拆分文件中都有 Feed 元素。

我试过以下方法,但效果不佳。

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/*">
    <xsl:for-each-group select="*" group-adjacent="(position()-1) idiv 9000">
      <xsl:result-document href="chunk{position()}.xml">
        <xsl:copy>
          <xsl:copy-of select="."/>
        </xsl:copy>
      </xsl:result-document>
    </xsl:for-each-group>
  </xsl:template>
</xsl:transform>

这没有正确分组,并且没有在每个文件中包含提要元素。

使用

<xsl:copy select="/*">
  <xsl:copy-of select="current-group()"/>
</xsl:copy>

如果您想使用 Saxon EE 和流媒体,我认为 xsl:copy select="/*" 将不起作用,但您可以使用 <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}"> 代替,例如

<xsl:template match="/*">
    <xsl:for-each-group select="*" group-adjacent="(position() - 1) idiv $chunk-size">
        <xsl:result-document href="split-{position()}.xml">
            <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}">
                <xsl:copy-of select="current-group()"/>
            </xsl:element>
        </xsl:result-document>
    </xsl:for-each-group>
</xsl:template>