在n个元素后将一个输出文件拆分为多个xml
Split one out-file into multiple xmls after n elements
我正在使用第 3 方软件生成 XML 文件。该软件允许使用 XSLT (2.0) 形式的 post 处理器。
我的输出文件比较大,经常达到几百MB,几百万行。我想分块我的输出文件并在每个文件之后有 1 个文件(比如说 10 个产品)而不是一个文件中的所有文件。
我在这里找到了一个 smiliar 线程:Split one XML file to multiple XML File with XSLT 但由于我是 XSLT 的新手,我无法弄清楚如何给出文件将被拆分的特定范围。我假设给定示例中的 xsl:for-each select="document/file">
是要查找的表达式,但我也不确定。
一个简单的XML看起来有点像这样:
<Products>
<Product ID="123" UserType="ITEM">
<Name>First Product</Name>
<Values>
<Value AttributeID="someAttribute">foo</Value>
<Value AttributeID="AnotherAttribute">bar</Value>
</Values>
</Product>
<Product ID="456" UserType="ITEM">
<Name>Second Product</Name>
<Values>
<Value AttributeID="someAttribute">foo</Value>
<Value AttributeID="AnotherAttribute">bar</Value>
</Values>
</Product>
</Products>
如上所述,有数千种产品,为了清晰的概述,我省略了 <Products>
-节点前后的节点。
如何将我的一个给定输出文件拆分为 N 个文件,假设在 10 个产品之后拆分这些文件?
假设 Products
元素是您可以使用的根元素的子元素,例如
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="size" as="xs:integer" select="2"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each-group select="*" group-adjacent="boolean(self::Products)">
<xsl:choose>
<xsl:when test="not(current-grouping-key()) and position() = 1">
<xsl:result-document href="headers.xml">
<Root>
<xsl:copy-of select="current-group()"/>
</Root>
</xsl:result-document>
</xsl:when>
<xsl:when test="current-grouping-key()">
<xsl:for-each-group select="current-group()/Product" group-by="(position() - 1) idiv $size">
<xsl:result-document href="chunk-{position()}.xml">
<Products>
<xsl:copy-of select="current-group()"/>
</Products>
</xsl:result-document>
</xsl:for-each-group>
</xsl:when>
<xsl:when test="not(current-grouping-key()) and position() = last()">
<xsl:result-document href="footers.xml">
<Root>
<xsl:copy-of select="current-group()"/>
</Root>
</xsl:result-document>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
我正在使用第 3 方软件生成 XML 文件。该软件允许使用 XSLT (2.0) 形式的 post 处理器。
我的输出文件比较大,经常达到几百MB,几百万行。我想分块我的输出文件并在每个文件之后有 1 个文件(比如说 10 个产品)而不是一个文件中的所有文件。
我在这里找到了一个 smiliar 线程:Split one XML file to multiple XML File with XSLT 但由于我是 XSLT 的新手,我无法弄清楚如何给出文件将被拆分的特定范围。我假设给定示例中的 xsl:for-each select="document/file">
是要查找的表达式,但我也不确定。
一个简单的XML看起来有点像这样:
<Products>
<Product ID="123" UserType="ITEM">
<Name>First Product</Name>
<Values>
<Value AttributeID="someAttribute">foo</Value>
<Value AttributeID="AnotherAttribute">bar</Value>
</Values>
</Product>
<Product ID="456" UserType="ITEM">
<Name>Second Product</Name>
<Values>
<Value AttributeID="someAttribute">foo</Value>
<Value AttributeID="AnotherAttribute">bar</Value>
</Values>
</Product>
</Products>
如上所述,有数千种产品,为了清晰的概述,我省略了 <Products>
-节点前后的节点。
如何将我的一个给定输出文件拆分为 N 个文件,假设在 10 个产品之后拆分这些文件?
假设 Products
元素是您可以使用的根元素的子元素,例如
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="size" as="xs:integer" select="2"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each-group select="*" group-adjacent="boolean(self::Products)">
<xsl:choose>
<xsl:when test="not(current-grouping-key()) and position() = 1">
<xsl:result-document href="headers.xml">
<Root>
<xsl:copy-of select="current-group()"/>
</Root>
</xsl:result-document>
</xsl:when>
<xsl:when test="current-grouping-key()">
<xsl:for-each-group select="current-group()/Product" group-by="(position() - 1) idiv $size">
<xsl:result-document href="chunk-{position()}.xml">
<Products>
<xsl:copy-of select="current-group()"/>
</Products>
</xsl:result-document>
</xsl:for-each-group>
</xsl:when>
<xsl:when test="not(current-grouping-key()) and position() = last()">
<xsl:result-document href="footers.xml">
<Root>
<xsl:copy-of select="current-group()"/>
</Root>
</xsl:result-document>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>