Java 如何拆分XML

Java 如何拆分XML,java,xml,xpath,mule,split,Java,Xml,Xpath,Mule,Split,我在这里的第一篇文章。我已经找过了,但还没有找到我要找的东西 我真的不确定我需要什么技术来完成下面的工作 我使用Mule 3.3 CE,需要拆分XML文件。我需要在每个分割的XML中保留“rootElement”及其属性。所有XML文件都将丢弃在同一JMS队列中 我知道如何分割三个产品节点,但如何在每个XML文件上保留“rootElement” XPath?XSLT?删除和添加节点? 我更喜欢XPath,但它有能力做到这一点吗 <?xml version="1.0" encoding="I

我在这里的第一篇文章。我已经找过了,但还没有找到我要找的东西

我真的不确定我需要什么技术来完成下面的工作

我使用Mule 3.3 CE,需要拆分XML文件。我需要在每个分割的XML中保留“rootElement”及其属性。所有XML文件都将丢弃在同一JMS队列中

我知道如何分割三个产品节点,但如何在每个XML文件上保留“rootElement”

XPath?XSLT?删除和添加节点? 我更喜欢XPath,但它有能力做到这一点吗

<?xml version="1.0" encoding="ISO-8859-1"?>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
           preOrderTo="2012-12-31T23:59:59"
           currency="GBP"
           timeStamp="2012-08-15T23:59:59">
  <Product
             itemID="09999-3-"
             name="Plate"
             description="Plate of blue man"
             tax="0.00"
             eanCode="1234567890123"
             eanType="EAN 13"/>
  <priceBracket quantity="1"
            price="10.98"
            grossPrice="13.00"/>
  <Product
             itemID="12345-3-"
             name="Plate"
             description="Plate of black man"
             tax="0.00"
             eanCode="1234569870123"
             eanType="EAN 13"/>
  <priceBracket quantity="1"
            price="15.98"
            grossPrice="18.00"/>
  <Product
             itemID="98765-3-"
             name="Plate"
             description="Plate of yellow man"
             tax="0.00"
             eanCode="7894567890123"
             eanType="EAN 13"/>
  <priceBracket quantity="1"
            price="20.98"
            grossPrice="24.00"/>
</rootElement>

我在Mule 3.3 CE中需要的是以下拆分:

一,


二,


三,



如何使用XPath进行拆分,然后使用XSLT转换器用rootElement包装每个结果?

如果可以使用XSLT 2.0,那么有一种方法

XML输入

<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
    preOrderTo="2012-12-31T23:59:59"
    currency="GBP"
    timeStamp="2012-08-15T23:59:59">
    <Product
        itemID="09999-3-"
        name="Plate"
        description="Plate of blue man"
        tax="0.00"
        eanCode="1234567890123"
        eanType="EAN 13"/>
    <priceBracket quantity="1"
        price="10.98"
        grossPrice="13.00"/>
    <Product
        itemID="12345-3-"
        name="Plate"
        description="Plate of black man"
        tax="0.00"
        eanCode="1234569870123"
        eanType="EAN 13"/>
    <priceBracket quantity="1"
        price="15.98"
        grossPrice="18.00"/>
    <Product
        itemID="98765-3-"
        name="Plate"
        description="Plate of yellow man"
        tax="0.00"
        eanCode="7894567890123"
        eanType="EAN 13"/>
    <priceBracket quantity="1"
        price="20.98"
        grossPrice="24.00"/>
</rootElement>

XSLT2.0

<xsl:stylesheet version="2.0" 
    xpath-default-namespace="http://Ecommerce.com/schemas/loyalist/3" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/*">
        <xsl:apply-templates select="*"/>
    </xsl:template>

    <xsl:template match="Product">
        <xsl:result-document href="{@itemID}.xml">
            <xsl:element name="{/*/name()}" 
                namespace="http://Ecommerce.com/schemas/loyalist/3">
                <xsl:copy-of select="/*/@*|.|following-sibling::priceBracket[1]"/>
            </xsl:element>
        </xsl:result-document>
    </xsl:template>

</xsl:stylesheet>

生成的XML文件(名称基于产品的itemID,但可以轻松更改)

09999-3-.xml

<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="09999-3-"
            name="Plate"
            description="Plate of blue man"
            tax="0.00"
            eanCode="1234567890123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="10.98" grossPrice="13.00"/>
</rootElement>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="12345-3-"
            name="Plate"
            description="Plate of black man"
            tax="0.00"
            eanCode="1234569870123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="15.98" grossPrice="18.00"/>
</rootElement>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="98765-3-"
            name="Plate"
            description="Plate of yellow man"
            tax="0.00"
            eanCode="7894567890123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="20.98" grossPrice="24.00"/>
</rootElement>

12345-3-.xml

<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="09999-3-"
            name="Plate"
            description="Plate of blue man"
            tax="0.00"
            eanCode="1234567890123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="10.98" grossPrice="13.00"/>
</rootElement>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="12345-3-"
            name="Plate"
            description="Plate of black man"
            tax="0.00"
            eanCode="1234569870123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="15.98" grossPrice="18.00"/>
</rootElement>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="98765-3-"
            name="Plate"
            description="Plate of yellow man"
            tax="0.00"
            eanCode="7894567890123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="20.98" grossPrice="24.00"/>
</rootElement>

98765-3-.xml

<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="09999-3-"
            name="Plate"
            description="Plate of blue man"
            tax="0.00"
            eanCode="1234567890123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="10.98" grossPrice="13.00"/>
</rootElement>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="12345-3-"
            name="Plate"
            description="Plate of black man"
            tax="0.00"
            eanCode="1234569870123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="15.98" grossPrice="18.00"/>
</rootElement>
<rootElement xmlns="http://Ecommerce.com/schemas/loyalist/3"
             preOrderTo="2012-12-31T23:59:59"
             currency="GBP"
             timeStamp="2012-08-15T23:59:59">
   <Product itemID="98765-3-"
            name="Plate"
            description="Plate of yellow man"
            tax="0.00"
            eanCode="7894567890123"
            eanType="EAN 13"/>
   <priceBracket quantity="1" price="20.98" grossPrice="24.00"/>
</rootElement>

下面是用编码将您的文档拆分为大约20行代码的代码

import com.ximpleware.*;
import java.io.*;
public class simpleSplit {
    public static void main(String[] s) throws VTDException, IOException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("input.xml", true)) //namespace awareness disabled
            return;
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        XMLModifier xm = new XMLModifier(vn);
        ap.selectXPath("/rootElement/product");
        int i=0,j=1;
        byte[] ba1 = ("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"+
                      "<rootElement xmlns=\"http://Ecommerce.com/schemas/loyalist/3\""+
                      "preOrderTo=\"2012-12-31T23:59:59\""+
                      "currency=\"GBP\""+
                      "timeStamp=\"2012-08-15T23:59:59\">\n").getBytes();
        byte[] ba =   "\n".getBytes();
        byte[] ba2 = "\n</rootElement>".getBytes();
        while((i=ap.evalXPath())!=-1){
            FileOutputStream fios = new FileOutputStream("file"+j+".xml");
            fios.write(ba1);//write starting tag
            vn.dumpFragment(fios);// write the product fragment
            fios.write(ba);
            if (vn.toElement(VTDNav.NEXT_SIBLING,"priceBracket")){
                // write the priceBracket fragment
                vn.dumpFragment(fios);
                vn.toElement(VTDNav.PREV_SIBLING);
            }
            fios.write(ba2);// write ending tag
            j++;
        }
    }
}
导入com.ximpleware.*;
导入java.io.*;
公共类simpleSplit{
公共静态void main(字符串[]s)引发VTDException、IOException{
VTDGen vg=新VTDGen();
如果(!vg.parseFile(“input.xml”,true))//名称空间感知已禁用
返回;
VTDNav vn=vg.getNav();
自动驾驶仪ap=新自动驾驶仪(vn);
XMLModifier xm=新的XMLModifier(vn);
ap.selectXPath(“/rootElement/product”);
int i=0,j=1;
字节[]ba1=(“”+
“\n”).getBytes();
byte[]ba=“\n”.getBytes();
字节[]ba2=“\n”.getBytes();
而((i=ap.evalXPath())!=-1){
FileOutputStream fios=新的FileOutputStream(“文件”+j+“.xml”);
fios.write(ba1);//写入起始标记
vn.dumpFragment(fios);//编写产品片段
fios.write(文学学士);
if(vn.toElement(VTDNav.NEXT_同胞,“价格括号”)){
//编写价格括号片段
vn.dumpFragment(fios);
vn.toElement(VTDNav.PREV_同胞);
}
fios.write(ba2);//写入结束标记
j++;
}
}
}

使用拆分器组件并在集合有效负载中添加根元素

<root>#[payload]</root>
#[有效载荷]

工作起来很有魅力。非常感谢你。没有XSLT还有其他可能的解决方案吗?有人吗?@ZiggyStardust我很好奇:如何处理流中XSL-T产生的多重输出?转换完成后,是否从文件系统重新加载文件?如果是,您是否生成唯一的文件名?还是这一切都发生在记忆中?嗨,大卫,我的想法正是如此。战略尚未决定。如何将拆分的文件重新接收到我的流中。或者我应该让一个“Folderwatcher”在一个新的流程中抓住它们?我的希望在于将它们发送到JMS队列,而不是像“正常”那样发送到文件和进程中。可能的现在说我们是否需要唯一的文件名还为时过早。我不需要长时间保存这些文件。很抱歉,你还没有真正的答案。事实证明,现在我们要跳过拆分,因为我们需要完整的文件作为事务(7.5Mb)。目前排序似乎有些过头了。