Split the large xml to smaller xml using XSLT.
Here is sample of source xml.
<?xml version="1.0" encoding="UTF-8"?>
<ABC>
<END />
<Tables>
<START>
<row>
<id>111</id>
<name>abc</name>
<deptId>1</deptId>
</row>
<row>
<id>112</id>
<name>abc1</name>
<deptId>1</deptId>
</row>
<row>
<id>113</id>
<name>abc3</name>
<deptId>1</deptId>
</row>
<row>
<id>222</id>
<name>def</name>
<deptId>2</deptId>
</row>
<row>
<id>333</id>
<name>pqr</name>
<deptId>2</deptId>
</row>
<row>
<id>444</id>
<name>xyz</name>
<deptId>2</deptId>
</row>
<row>
<id>555</id>
<name>lmn</name>
<deptId>3</deptId>
</row>
<row>
<id>555</id>
<name>lmn</name>
<deptId>3</deptId>
</row>
</START>
</Tables>
</ABC>
I have a xml with the above structure.
I have to spilt the xml into 3 xml's based on the different deptId.
I have to Split the xml into smaller one based on change in tag values.
My elemement is deptId whose values is been changed after some rows.
The all elements with same deptId are in a sequence.
The required output is : Its good to have the xml name as the department id.
The first xml be with name 1.xml :
<?xml version="1.0" encoding="UTF-16"?>
<ABC>
<END />
<Tables>
<START>
<row>
<id>111</id>
<name>abc</name>
<deptId>1</deptId>
</row>
<row>
<id>112</id>
<name>abc1</name>
<deptId>1</deptId>
</row>
<row>
<id>113</id>
<name>abc3</name>
<deptId>1</deptId>
</row>
</START>
</Tables>
</ABC>
The solution to the above the problem is to use the XSLT.
Create a xsl file like below.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:for-each-group select="//ABC//Tables//START//row" group-adjacent="deptId">
<xsl:variable name="file" select="concat(deptId,'.xml')"/>
<xsl:result-document href="{$file}">
<ABC>
<END />
<Tables>
<START>
<xsl:copy-of select="current-group()"/>
</START>
</Tables>
</ABC>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:transform>
Here is the sample piece of java code that need to run.
package com.java.xml;
import java.io.File;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.Xslt30Transformer;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
public class SplitXml {
public static void main(String[] args) {
Processor proc = new Processor(false);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp;
try {
exp = comp.compile(new StreamSource(new File("E://test.xsl")));
Serializer out = proc.newSerializer(new File("E://output.xml"));
Xslt30Transformer trans = exp.load30();
trans.applyTemplates(new StreamSource(new File("E://source.xml")),
out);
} catch (SaxonApiException e) {
e.printStackTrace();
}
}
}
Here is sample of source xml.
<?xml version="1.0" encoding="UTF-8"?>
<ABC>
<END />
<Tables>
<START>
<row>
<id>111</id>
<name>abc</name>
<deptId>1</deptId>
</row>
<row>
<id>112</id>
<name>abc1</name>
<deptId>1</deptId>
</row>
<row>
<id>113</id>
<name>abc3</name>
<deptId>1</deptId>
</row>
<row>
<id>222</id>
<name>def</name>
<deptId>2</deptId>
</row>
<row>
<id>333</id>
<name>pqr</name>
<deptId>2</deptId>
</row>
<row>
<id>444</id>
<name>xyz</name>
<deptId>2</deptId>
</row>
<row>
<id>555</id>
<name>lmn</name>
<deptId>3</deptId>
</row>
<row>
<id>555</id>
<name>lmn</name>
<deptId>3</deptId>
</row>
</START>
</Tables>
</ABC>
I have a xml with the above structure.
I have to spilt the xml into 3 xml's based on the different deptId.
I have to Split the xml into smaller one based on change in tag values.
My elemement is deptId whose values is been changed after some rows.
The all elements with same deptId are in a sequence.
The required output is : Its good to have the xml name as the department id.
The first xml be with name 1.xml :
<?xml version="1.0" encoding="UTF-16"?>
<ABC>
<END />
<Tables>
<START>
<row>
<id>111</id>
<name>abc</name>
<deptId>1</deptId>
</row>
<row>
<id>112</id>
<name>abc1</name>
<deptId>1</deptId>
</row>
<row>
<id>113</id>
<name>abc3</name>
<deptId>1</deptId>
</row>
</START>
</Tables>
</ABC>
The solution to the above the problem is to use the XSLT.
Create a xsl file like below.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:for-each-group select="//ABC//Tables//START//row" group-adjacent="deptId">
<xsl:variable name="file" select="concat(deptId,'.xml')"/>
<xsl:result-document href="{$file}">
<ABC>
<END />
<Tables>
<START>
<xsl:copy-of select="current-group()"/>
</START>
</Tables>
</ABC>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:transform>
Here is the sample piece of java code that need to run.
package com.java.xml;
import java.io.File;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.Xslt30Transformer;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
public class SplitXml {
public static void main(String[] args) {
Processor proc = new Processor(false);
XsltCompiler comp = proc.newXsltCompiler();
XsltExecutable exp;
try {
exp = comp.compile(new StreamSource(new File("E://test.xsl")));
Serializer out = proc.newSerializer(new File("E://output.xml"));
Xslt30Transformer trans = exp.load30();
trans.applyTemplates(new StreamSource(new File("E://source.xml")),
out);
} catch (SaxonApiException e) {
e.printStackTrace();
}
}
}