使用基于元素计数的XSLT 2.0拆分XML文件

时间:2016-01-08 21:18:36

标签: java xml xslt

具有以下结构的巨大XML:

<?xml version="1.0" encoding="UTF-8"?>
<productall>

<product type="electronics" date="1-1-2016">

<type name"Androidbased">

      <product> InStock </product>

</type>      

</product>

<product type="cloths" date="1-12-2008">

<type name"Jeans">

      <product> InStock </product>

</type>      

</product>

<product type="bags" date="1-12-2008">

<type name"FF">

      <product> InStock </product>

</type>      

</product>


</productall>

每种产品类型都有数千条记录,例如电子产品是2000条记录,布料是8000条记录。

我想将此XML文件拆分为多个XML,每个记录包含1000条记录,无论类型如何!

我使用过基于java&amp;的XSLT 2.0。撒克逊9分裂它但它不起作用,因为它应该是我到目前为止所做的:

java -jar sax.jar productall.xml split.xslt

Split.xslt

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="productall" select="1000"></xsl:param>
    <xsl:template match="/productall/product[@type]">
        <xsl:for-each-group select="product" group-adjacent="(position()-1) idiv $productall">
            <xsl:result-document href="part.{current-grouping-key()}.xml">
                <productall>
                    <xsl:copy-of select="current-group()"></xsl:copy-of>
                </productall>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

结果将在没有XML格式的终端屏幕上打印出来,并且不会生成.XML文件。不知道命令语法或XSLT文件的内容有什么问题?

2 个答案:

答案 0 :(得分:1)

此处的主要问题是您的模板与product元素匹配,这意味着当您执行xsl:for-each-group时,您将位于product元素上。然后你选择了product元素,这些元素不是当前元素的子元素,而是type元素的子元素。所以,你需要这样做......

<xsl:for-each-group select="type/product" group-adjacent="(position()-1) idiv $productall">

但是,您说您希望多个XML具有1000条记录,无论类型如何,但是当前的XSLT分别为每个主要产品执行此操作,这意味着您将获得重复的文件名。

也许您应该在文件名中包含主要产品类型?

<result-document href="part.{../../@type}.{current-grouping-key()}.xml">

或者如果您确实想要这样做而不管主要产品类型如何,您应该更改主模板以匹配productall

试试这个XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="productall" select="1000"></xsl:param>
    <xsl:template match="/productall">
         <xsl:for-each-group select="product/type/product" group-adjacent="(position()-1) idiv $productall">
            <xsl:result-document href="part.{current-grouping-key()}.xml">
                <productall>
                    <xsl:copy-of select="current-group()"></xsl:copy-of>
                </productall>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

我认为您只需将match="/productall/product[@type]"更改为match="/productall"