根据属性值拆分 XML 文件
Split XML file according attribute's value
需要根据属性值拆分 XML 文件。可以使用 XSLT-1.0 吗?如果无法使用 1.0 版本完成它,我将不胜感激任何更高版本的 XSLT 代码。
这是一个数字拆分属性值(10、11、12 等)。但我想解决方案的原则对于数字和非数字序列可能是通用的。当系统找到第一个新的(更改的)split-attribute 值时生成新文件。
(可选问题)。这些操作需要多大的 XML 文件?是否可以处理 3gb 文件? 30GB文件? RAM 是否有任何系统要求来处理这样的文件大小?
来源:
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
</objects>
期望输出
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
</objects>
<!--=========================== file-1.xml ======================-->
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
</objects>
<!--=========================== file-2.xml ======================-->
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
</objects>
<!--=========================== file-3.xml ======================-->
这可以通过 XSLT-2.0 及更高版本来完成。 2.0 版本引入了所需的 xsl:result-document 函数。
现在解决方案很简单:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/objects">
<xsl:for-each-group select="obj" group-by="@split-attribute">
<xsl:result-document href="{concat('File-',position(),'.xml')}" indent="yes">
<objects>
<xsl:copy-of select="current-group()" />
</objects>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
输出符合要求,由三个单独的文件组成。
你有一个很好的 XSLT 2.0 答案,尽管我认为使用 group-adjacent
更能满足你的需要 ("new file is produced when system finds the first new (changed) value of split-attribute");要使其与 XSLT 3 和流式传输(以及支持它的处理器,如 Saxon 9 EE)一起使用,您可以使用
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode stremable="yes"/>
<xsl:template match="/objects">
<xsl:for-each-group select="obj" group-adjacent="@split-attribute">
<xsl:result-document href="file-{position()}.xml" indent="yes">
<objects>
<xsl:copy-of select="current-group()" />
</objects>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
这样它甚至可以处理非常大的文件。
需要根据属性值拆分 XML 文件。可以使用 XSLT-1.0 吗?如果无法使用 1.0 版本完成它,我将不胜感激任何更高版本的 XSLT 代码。
这是一个数字拆分属性值(10、11、12 等)。但我想解决方案的原则对于数字和非数字序列可能是通用的。当系统找到第一个新的(更改的)split-attribute 值时生成新文件。
(可选问题)。这些操作需要多大的 XML 文件?是否可以处理 3gb 文件? 30GB文件? RAM 是否有任何系统要求来处理这样的文件大小?
来源:
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
</objects>
期望输出
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="10"/>
</objects>
<!--=========================== file-1.xml ======================-->
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="11"/>
</objects>
<!--=========================== file-2.xml ======================-->
<objects>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
<obj attribute-1="value" attribute-2="value2" split-attribute="12"/>
</objects>
<!--=========================== file-3.xml ======================-->
这可以通过 XSLT-2.0 及更高版本来完成。 2.0 版本引入了所需的 xsl:result-document 函数。
现在解决方案很简单:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/objects">
<xsl:for-each-group select="obj" group-by="@split-attribute">
<xsl:result-document href="{concat('File-',position(),'.xml')}" indent="yes">
<objects>
<xsl:copy-of select="current-group()" />
</objects>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
输出符合要求,由三个单独的文件组成。
你有一个很好的 XSLT 2.0 答案,尽管我认为使用 group-adjacent
更能满足你的需要 ("new file is produced when system finds the first new (changed) value of split-attribute");要使其与 XSLT 3 和流式传输(以及支持它的处理器,如 Saxon 9 EE)一起使用,您可以使用
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode stremable="yes"/>
<xsl:template match="/objects">
<xsl:for-each-group select="obj" group-adjacent="@split-attribute">
<xsl:result-document href="file-{position()}.xml" indent="yes">
<objects>
<xsl:copy-of select="current-group()" />
</objects>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
这样它甚至可以处理非常大的文件。