如何拆分XML

3

这是我在此处发布的第一篇文章。我已经搜索过了,但没有找到我需要的内容。

我不确定我需要使用什么技术来完成以下操作。

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

我知道如何拆分三个Product节点,但我如何在每个XML文件上保留“rootElement”?

XPath?XSLT?DOM并删除和添加节点?我更喜欢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中,我需要分割以下内容:
1.
<?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"/>
</rootElement>

2.

<?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="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>

3.

<?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="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>
4个回答

0
使用分割器组件并在设置有效负载时添加根元素。
<root>#[payload]</root>

0
如果您可以使用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>

XSLT 2.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>

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="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>

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="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>

运行得非常好。非常感谢。还有其他可能的解决方案,不需要使用XSLT吗?有人知道吗? - ZiggyStardust
@ZiggyStardust 我很好奇:在你的流程中,你是如何处理 XSL-T 产生的多个输出的?转换完成后,你是否从文件系统重新加载文件?如果是这样,你会生成唯一的文件名吗?还是这一切都发生在内存中? - David Dossot
嗨David,我的想法完全一致。策略还没有决定。我如何将分割文件再次接收到我的流中?或者我应该只有一个“Folderwatcher”并在新的流中抓取它们?我希望将它们发送到JMS队列而不是输出到文件并作为“正常”处理。可能吗?现在还为时过早,无法确定是否需要唯一的文件名。我不需要长时间存储文件。很抱歉,我还没有真正的答案给你。事实证明,目前我们正在跳过拆分,因为我们需要完整的文件作为交易(7.5Mb)。目前来看,排序似乎有些过度了。 - ZiggyStardust

0

使用XPath进行分割,然后使用XSLT转换器将每个结果包装在rootElement中怎么样?


-1
以下是将您的文档使用vtd-xml编码拆分的代码,大约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++;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接