Hussey123 Hussey123 - 22 days ago 11
Java Question

Split XML using SAX parser

I have following xml file.

<Engineers>
<Engineer>
<Name>JOHN</Name>
<Position>STL</Position>
<Team>SS</Team>
</Engineer>
<Engineer>
<Name>UDAY</Name>
<Position>TL</Position>
<Team>SG</Team>
</Engineer>
<Engineer>
<Name>INDRA</Name>
<Position>Director</Position>
<Team>PP</Team>
</Engineer>
</Engineers>


I need to split this xml into smaller xml strings when Xpath is given as Engineers/Enginner.

Smaller xml strings are as follows

<Engineers>
<Engineer>
<Name>INDRA</Name>
<Position>Director</Position>
<Team>PP</Team>
</Engineer>
</Engineers>

<Engineers>
<Engineer>
<Name>JOHN</Name>
<Position>STL</Position>
<Team>SS</Team>
</Engineer>
</Engineers>


I have implemented following so far using SAX which we can get the elements inside XML but not as what I want.How can I proceed??

public class ReadSAX
{
public static void main( String[] args )
{
try {

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

DefaultHandler handler = new DefaultHandler() {

public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {

System.out.println("Start Element :" + qName);



public void endElement(String uri, String localName,
String qName)
throws SAXException {

System.out.println("End Element :" + qName);

}

public void characters(char ch[], int start, int length)
throws SAXException {

System.out.println(new String(ch, start, length));


}

};

File file = new File("c:\\file.xml");
InputStream inputStream= new FileInputStream(file);
Reader reader = new InputStreamReader(inputStream,"UTF-8");

InputSource is = new InputSource(reader);
is.setEncoding("UTF-8");

saxParser.parse(is, handler);


} catch (Exception e) {
e.printStackTrace();
}

}
}

Answer

Why use such a low-level coding approach?

In XSLT 2.0 it's simply

<xsl:template match="/">
  <xsl:for-each select="Engineers/Engineer">
    <xsl:result-document select="{position()}.xml">
      <Engineers>
        <xsl:copy-of select="."/>
      </Engineers>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template> 

and if that takes too much memory, get a streaming XSLT 3.0 processor which will solve the problem.