How to split XML

My first post is here. I searched, but did not find what I was looking for.

I'm not quite sure what technique I need to do.

I am using Mule 3.3 CE and I need to split the XML files. I need to store the "rootElement" and its attributes in each shared XML. All XML files will be deleted in the same JMS queue.

I know how to separate the three Product nodes, but how can I save the "rootElement" in each XML file?

XPath? XSLT? DOM and delete and add nodes? I would rather just have XPath, but does it have the power to do this?

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

What I need in Mule 3.3 CE is the following split:

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
source share
4 answers

If you can use XSLT 2.0, here is one way ...

XML input

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

The resulting XML files (a name based on the itemID of the product, but can be easily changed) ...

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> 
+1
source

What about XPath for splitting and then an XSLT transformer to wrap each result with rootElement?

0
source

Below is the code to split your document into vtd-xml coding in about 20 lines of code ....

 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++; } } } 
0
source

use the splitter component and add the root element to the given payload

 <root>#[payload]</root> 
0
source

All Articles