Split XML file according attribute's value
需要根据属性值拆分XML文件。是否可以使用XSLT-1.0?如果没有可能用1.0版本做到这一点,我将不胜感激任何更高版本的XSLT代码。
这是数字拆分属性的值(10、11、12等)。但是我想解决方案的原理对于数字和非数字序列可能是通用的。当系统找到split-attribute的第一个新(更改)值时,将生成新文件。
(可选问题)。这些操作可能有多少个XML文件?是否可以处理3gb文件? 30GB档案? RAM是否有任何系统要求来处理此类文件大小?
来源:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <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> |
期望的输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <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及更高版本来完成。所需的xsl:result-document函数是在2.0版中引入的。
现在解决方案很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <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答案,尽管即使在我看来,使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <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> |
这样,它甚至应该可以处理非常大的文件。