需要根据属性值分割XML文件。是否可以使用XSLT-1.0?如果没有可能用1.0版本做到这一点,我将不胜感激任何更高版本的XSLT代码。
这里是数字拆分属性的值(10、11、12等)。但是我想解决方案的原理对于数字和非数字序列可能是通用的。系统找到第一个新的(更改的)拆分属性值后,便会生成新文件。
(可选问题)。这些操作可能有多少个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 ======================-->
答案 0 :(得分:2)
这可以使用XSLT-2.0及更高版本来完成。所需的xsl:result-document函数是在2.0版中引入的。
现在解决方案很简单:
<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>
输出是所需的,并且包含三个单独的文件。
答案 1 :(得分:0)
您有一个不错的XSLT 2.0答案,尽管我认为使用group-adjacent
仍然可以满足您的需要(“当系统找到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>
这样,它甚至应该可以处理非常大的文件。