简体   繁体   English

使用XSLT 2.0根据元素计数拆分XML文件

[英]Split XML file with XSLT 2.0 based on element count

Huge XML with the following structure : 具有以下结构的巨大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>

each product type has thousands of records for example electronics are 2000 records and cloths are 8000 records. 每种产品类型都有数千条记录,例如电子产品为2000条记录,布料为8000条记录。

I want to split this XML file into multiple XMLs with 1000 records each regardless the type! 我想将此XML文件拆分为多个XML,每个XML具有1000条记录,而与类型无关!

I have used XSLT 2.0 based on java & saxon 9 to split it but it doesn't work as it should here is what I did so far : 我已经使用了基于Java和Saxon 9的XSLT 2.0来拆分它,但是它不起作用,因为这是我到目前为止所做的:

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

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>

The result is printed out on the terminal screen without XML format and no .XML files are generated. 结果将在没有XML格式的终端屏幕上打印出来,并且不会生成.XML文件。 Don't know what is wrong the command syntax or the contents of the XSLT file? 不知道命令语法或XSLT文件的内容有什么问题吗?

The main problem here is your template matches a product element, which means when you do the xsl:for-each-group , you will be positioned on the product element. 这里的主要问题是您的模板与product元素匹配,这意味着当您执行xsl:for-each-group ,您将位于product元素上。 Then you are selecting product elements, ye the these are not children of the current element, but of the type elements. 然后,您要选择product元素,这不是当前元素的子元素,而是type元素的子元素。 So, you need to do this... 所以,您需要这样做...

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

However, you say you want multiple XMLs with 1000 records each regardless the type, but the current XSLT does this for each main product separately, meaning you will get duplicate file names. 但是,您说您想要多个XML,每个XML具有1000条记录,而不管类型如何,但是当前的XSLT对每个主要产品分别执行此操作,这意味着您将获得重复的文件名。

Perhaps you should include the main product type in the file name? 也许您应该在文件名中包含主要产品类型?

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

Or if you really did want to do it regardless of main product type, you should change your main template to match productall instead. 或者,如果您确实确实想这样做而与主要产品类型无关,则应更改主模板以匹配productall

Try this XSLT 试试这个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>

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM