I have a XML string/object:
<?xml version="1.0"?>
<ns0:top xmlns:ns0="someUrl1">
<ns1:child xmlns:ns1="someUrl2">
Value
</ns1:child>
</ns0:top>
How can I transform in to "normalized" namespaces XML form like this:
<?xml version="1.0"?>
<ns0:top xmlns:ns0="someUrl1" xmlns:ns1="someUrl2">
<ns1:child>
Value
</ns1:child>
</ns0:top>
This might be a bad idea for a few reasons (it's going to be hard to cover lots of edge cases), but (for fun and for very simple cases like the one you posed) here's an implementation using SAXParser that does this:
/* package whatever; // don't place package name! */
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone extends DefaultHandler
{
StringBuilder sb;
private Hashtable namespaces;
private int nsIdx;
boolean rootDone;
String rootNodeName;
String rootNS;
public void startDocument() throws SAXException {
namespaces = new Hashtable();
nsIdx = 0;
sb = new StringBuilder();
rootDone = false;
}
public void endDocument() throws SAXException {
Set<String> keys = namespaces.keySet();
StringBuilder rootEl = new StringBuilder();
rootEl.append("<" + namespaces.get(rootNS) + ":" + rootNodeName);
for(String key: keys){
rootEl.append(" xmlns:" + namespaces.get(key) + "='" + key + "'");
}
rootEl.append(">");
sb.insert(0, rootEl.toString());
System.out.println(sb.toString());
}
public void characters(char[] ch, int start, int length) throws SAXException {
for (int i = start; i < start + length; i++)
{
sb.append(ch[i]);
}
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (!namespaces.containsKey(namespaceURI))
{
nsIdx++;
namespaces.put(namespaceURI, "ns" + nsIdx);
}
boolean printEl = rootDone;
if (!rootDone)
{
rootNodeName = localName;
rootNS = namespaceURI;
rootDone = true;
}
else
{
sb.append("<" + namespaces.get(namespaceURI) + ":" + localName);
}
for (int i = 0; i < atts.getLength(); i++)
{
if (!namespaces.containsKey(atts.getURI(i)))
{
nsIdx++;
namespaces.put(atts.getURI(i),"ns" + nsIdx);
}
if (atts.getLocalName(i) == atts.getQName(i))
{
sb.append(" " + atts.getLocalName(i) + "='" + atts.getValue(i) + "'");
}
else
{
sb.append(" " + namespaces.get(atts.getURI(i)) + ":" + atts.getLocalName(i) + "='" + atts.getValue(i) + "'");
}
}
if (printEl)
{
sb.append(">");
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
sb.append("</" + namespaces.get(uri) + ":" + localName + ">");
}
public static void main (String[] args) throws java.lang.Exception
{
String xml = "<?xml version=\"1.0\"?><ns0:top xmlns:ns0=\"someUrl1\"><ns1:child xmlns:ns1=\"someUrl2\" ns0:testNS=\"tstNS\" test=\"tst\">Value</ns1:child><child2></child2><child3/></ns0:top>";
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser saxParser = spf.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(new Ideone());
xmlReader.parse(new InputSource(new StringReader(xml)));
}
}
(ideone: http://ideone.com/E4LIac)
Note that this will do the following things that may not be desireable:
Make nodes that were self closing be empty (e.g. <child3 /> becomes <child3></child3>)
Create prefixes for unprefixed nodes (e.g. xmlns:ns3='')
Probably doesn't properly handle some other edge cases
Probably doesn't follow the best Java conventions, I'm a bit rusty there
Also note that it just prints the final result out to System.out - you'd likely want to return it or save it or something else. And I have no idea if or how this would work in groovy.
Related
I am trying to run this code and ArrayList data = handler.getnames(); is showing an error variable data is alredy defined in method main(String[]). I am guessing it wants me to combine it with ArrayList data = handler.getsetnums();. But how to i do it? or is there another way?
Ones the code works, and should be able to run it and get an output, now when i only have one Array working the code does what it needs to do.
expected outcome
<set-num>00-1</set-num>
<name>WEETABIX CASTLE</name>
Thank you.
---MAIN.java---
package assign6;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
*
* #author assign
*/
public class Assign6 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.print("Welcome to Benjamin Bolyard's Lego Sorter");
try {
XMLReader reader = XMLReaderFactory.createXMLReader();
MyHandler handler = new MyHandler();
reader.setContentHandler(handler);
reader.setErrorHandler(handler);
InputSource inputSource = new InputSource("legoSets.xml");
reader.parse(inputSource);
ArrayList<String> data = handler.getsetnums();
System.out.println("setnum List");
System.out.println("----------");
for (int i = 0; i < data.size(); i++) {
String setnum = data.get(i);
setnum = setnum.toUpperCase();
System.out.println((i + 1) + ": " + setnum);
}
ArrayList<String> data = handler.getnames();
System.out.println("name List");
System.out.println("----------");
for (int i = 0; i < data.size(); i++) {
String name = data.get(i);
name = name.toUpperCase();
System.out.println((i + 1) + ": " + name);
}
} catch (SAXException ex) {
Logger.getLogger(BolyardAssign6.class.getName())
.log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(BolyardAssign6.class.getName())
.log(Level.SEVERE, null, ex);
}
}
}
--HANDLER.java---
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package bolyardassign6;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
* #author bolya
*/
public class MyHandler extends DefaultHandler {
private boolean inlegosets;
private boolean inname;
private boolean insetnum;
private String nameBuffer;
private String setnumBuffer;
private ArrayList<String> setnums, names;
public ArrayList<String> getsetnums() {
return setnums;
}
public ArrayList<String> getnames() {
return names;
}
#Override
public void startDocument() throws SAXException {
// System.out.println("Start Document")
insetnum = false;
inname = false;
inlegosets = false;
nameBuffer = "";
names = new ArrayList<>();
}
#Override
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
if (localName.equals("lego-sets")) {
inlegosets = true;
} else if (inlegosets && localName.equals("setnum")) {
// System.out.println("Start element : " + localName);
insetnum = true;
setnumBuffer = "";
} else if (inlegosets && localName.equals("name")) {
// System.out.println("Start element : " + localName);
inname = true;
nameBuffer = "";
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
String data = new String(ch, start, length);
if (inlegosets && inname) {
// System.out.println("Characters : " + data);
nameBuffer = nameBuffer + data;
} else if (inlegosets && insetnum) {
// System.out.println("Characters : " + data);
setnumBuffer = setnumBuffer + data;
}
}
#Override
public void endElement(String uri, String localName,
String qName) throws SAXException {
if (localName.equals("inlegosets")) {
inlegosets = false;
} else if (inlegosets && localName.equals("setnum")) {
// System.out.println("Title: " + titleBuffer);
// System.out.println("End element : " + localName);
// System.out.println();
setnums.add(setnumBuffer);
insetnum = false;
} else if (inlegosets && localName.equals("name")) {
// System.out.println("Title: " + titleBuffer);
// System.out.println("End element : " + localName);
// System.out.println();
names.add(nameBuffer);
inname = false;
}
}
#Override
public void endDocument() throws SAXException {
// System.out.println("End Document");
}
#Override
public void error(SAXParseException e) throws SAXException {
System.out.println("ERROR: Line number " + e.getLineNumber());
System.out.println("ERROR: " + e.getMessage());
}
#Override
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("FATAL ERROR: Line number " + e.getLineNumber());
System.out.println("FATAL ERROR: " + e.getMessage());
}
}
---legoset.xml---
<lego-sets>
<set>
<set-num>00-1</set-num>
<name>WEETABIX CASTLE</name>
<year>1970</year>
<num-parts>471</num-parts>
</set>
<set>
<set-num>0011-2</set-num>
<name>TOWN MINI-FIGURES</name>
<year>1978</year>
<num-parts>12</num-parts>
</set>
<set>
<set-num>0011-3</set-num>
<name>CASTLE 2 FOR 1 BONUS OFFER</name>
<year>1987</year>
<num-parts>2</num-parts>
</set>
<set>
<set-num>0012-1</set-num>
<name>SPACE MINI-FIGURES</name>
<year>1979</year>
<num-parts>12</num-parts>
</set>
</lego-sets>
You have defined two variables with the name data. To fix this, change the name of one of them. Alternatively you can remove the declaration and just have the following on the second arraylist: data = handler.getnames();
I am trying to run this code and ArrayList data = handler.getnames(); is showing an error variable data is alredy defined in method main(String[]). I am guessing it wants me to combine it with ArrayList data = handler.getsetnums();. But how to i do it? or is there another way?
You have the right idea. The error is caused because you have two variable declarations withe same name:
ArrayList data = handler.getnames()
and
ArrayList data = handler.getsetnums();
Java doesn't allow this. However, you don't necessarily want to "combine them together" because these are two separate lists that seem to represent two different things.
I suggest changing the names of both variables to something more meaningful than data. For example:
ArrayList names = handler.getnames()
and
ArrayList setnums = handler.getsetnums();
Presumably, names and setnums represent something meaningful for what you are doing here.
I have big xml files (~1GB) with this structure:
<?xml version="1.0" encoding="UTF-8"?>
<GenoExchange xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ncbi.nlm.nih.gov/SNP/geno" xsi:schemaLocation="http://www.ncbi.nlm.nih.gov/SNP/geno ftp://ftp.ncbi.nlm.nih.gov/snp/specs/genoex_1_5.xsd" dbSNPBuildNo="146" reportId="MT" reportType="chromosome">
<Population popId="638" handle="TSC-CSHL" locPopId="TSC_42_AA">
<popClass self="NORTH AMERICA"/>
</Population>
<SnpInfo rsId="1041870" observed="C/T">
<SnpLoc genomicAssembly="107:GRCh38.p2" geneId="4512" geneSymbol="COX1" chrom="MT" start="6150" locType="2" rsOrientToChrom="fwd" contigAllele="T" contig="NC_012920:1"/>
<SsInfo ssId="1508548" locSnpId="TSC0349089" ssOrientToRs="fwd">
<ByPop popId="1303" sampleSize="184">
<AlleleFreq allele="T" freq="1"/>
<AlleleFreq allele="C" freq="0"/>
</ByPop>
</SsInfo>
</SnpInfo>
<SnpInfo rsId="1029293" observed="C/T">
<SnpLoc genomicAssembly="107:GRCh38.p2" geneId="4512" geneSymbol="COX1" chrom="MT" start="6307" locType="2" rsOrientToChrom="fwd" contigAllele="C" contig="NC_012920:1"/>
<SsInfo ssId="1494519" locSnpId="TSC0254145" ssOrientToRs="fwd">
<ByPop popId="639" sampleSize="82">
<AlleleFreq allele="T" freq="0"/>
<AlleleFreq allele="C" freq="1"/>
</ByPop>
<ByPop popId="1303" sampleSize="184">
<AlleleFreq allele="T" freq="0"/>
<AlleleFreq allele="C" freq="1"/>
</ByPop>
</SsInfo>
</SnpInfo>
I want to find a specific rsID, for example rsID="1029293" and extract all the information inside that node. I don't want to run all the file. I only want to find that ID, extract that information and end the iteration.
From what I read it's better if I use SAX or Stax parsers. I'm using SAX, this is my code:
class UserHandler extends DefaultHandler {
String rsID = null;
String i = "1029293";
#Override
public void startElement(String uri,
String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("SnpInfo")) {
rsID = attributes.getValue("rsId");
//System.out.println("value: " + rsID);
}
if((i).equals(rsID) &&
qName.equalsIgnoreCase("SnpInfo")){
System.out.println("Start Element: " + qName + " " + rsID);
}
if ((i).equals(rsID) && qName.equalsIgnoreCase("SsInfo")) {
String a = attributes.getValue("ssId");
System.out.println("SSID: " + a);
}
if ((i).equals(rsID) && qName.equalsIgnoreCase("ByPop")) {
String p = attributes.getValue("popId");
System.out.println("POPID: " + p);
}
if ((i).equals(rsID) && qName.equalsIgnoreCase("AlleleFreq")) {
String p = attributes.getValue("allele");
String f = attributes.getValue("freq");
System.out.println("ALLELE: " + p + " FREQ: " + f);
}
if ((i).equals(rsID) && qName.equalsIgnoreCase("GTypeFreq")) {
String p = attributes.getValue("gtype");
String f = attributes.getValue("freq");
System.out.println("GTYPE: " + p + " FREQ: " + f);
}
}
#Override
public void endElement(String uri,
String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("SnpInfo")) {
if((i).equals(rsID)
&& qName.equalsIgnoreCase("SnpInfo"))
System.out.println("End Element: " + qName);
}
}
}
public class XMLParser {
public static void main(String argv[]) {
try {
InputStream fileStream = new FileInputStream("/home/xml/gt_chr10.xml.gz");
InputStream gzipStream = new GZIPInputStream(fileStream);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
UserHandler userhandler = new UserHandler();
saxParser.parse(gzipStream, userhandler);
} catch (Exception e) {
e.printStackTrace();
}
}
My problem is that my code searches the whole file for the ID and that takes more than 2 minutes each time. I can't have a code that takes so long.
Is there a better approach for this?
Using STAX gives you more control when parsing XML, since you actively pull elements from the stream. This way you can pull the next event, handle it and once you found your data, simply terminate the loop (using a flag or even a return statement if you must)
InputStream in = ...
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(in);
boolean found = false;
while (!found && eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
switch (event.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
// your logic here
// once you found your element, you can terminate the loop
found = true;
break;
case XMLStreamConstants.END_ELEMENT:
// your logic here
break;
}
}
(omitted exception and resource handling for brevity)
On a side note, you will gain some performance by combining your if ((i).equals(rsID) && ... into a single one, with detail checks in nested ifs
if ((i).equals(rsID)) {
if(qName.equalsIgnoreCase("GTypeFreq")) {
...
}
}
You can throw an exception in your end element handler, to indicate to the parser that it aborts parsing (http://www.ibm.com/developerworks/library/x-tipsaxstop/):
#Override
public void endElement(String uri,
String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("SnpInfo")) {
if((i).equals(rsID)
&& qName.equalsIgnoreCase("SnpInfo"))
System.out.println("End Element: " + qName);
throw SAXException("Element found.");
}
}
The only way to avoid parsing the whole file every time you run this is to put the data in an XML database. Parsing a 1Gb file is going to take about a minute, plus or minus depending on the speed of your machine and what processing you do on each node.
A streamed XSLT 3.0 solution is simply:
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://www.ncbi.nlm.nih.gov/SNP/geno">
<xsl:template name="xsl:initial-template">
<xsl:stream href="input.xml">
<xsl:copy-of select="/GenoExchange/SnpInfo[#rsId='1041870'][1]"/>
</xsl:stream>
</xsl:template>
</xsl:transform>
No need to write all that pesky SAX or StAX code.
I put the "[1]" predicate in to allow the processor to abandon the search when it has found the first hit.
The best approach is to use vtd-xml and xpath... 1GB xml file takes about 1.5GB heap space and < 10 sec in a 3~4 year old intel processor.see code example below.. One more thing, if you want to eliminate parsing entirely, you can create a vtd+XML file format so any subsequent query can directly access the vtd index portion, which could easily triple or quadruple your app performance...
import com.ximpleware.*;
public class simpleXpathSearch{
public static void main(String s[]) throws VTDException,java.io.UnsupportedEncodingException,java.io.IOException{
VTDGen vg = new VTDGen();
vg.setLCLevel(5);
if (!vg.parseFile("input.xml", false))
return;
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/*/*[#rsID='1029293']");
int i=0;
while((i=ap.evalXPath())!=-1){
// your code logic here
}
//Main class
public static void main(String[] args) {
SAXReader.read();
}
//SAXReader
public static void read(){
try {
XMLReader processor = XMLReaderFactory.createXMLReader();
processor.setContentHandler(new SAXController());
processor.parse(new InputSource("MyXML.xml"));
} catch (SAXException | IOException e) {
System.err.println(e.getMessage());
}
}
//SAXController
// The SAXController extends DefaultHandler
private int tab = 0;
private void tabulation() {
for (int i=0; i<tab; i++)
System.out.print(" ");
}
#Override
public void startDocument() {
tabulation();
System.out.println("Starting XML Document");
tab++;
}
#Override
public void endDocument() {
tab--;
tabulation();
System.out.println("Ending XML Document");
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
tabulation();
System.out.print(localName);
if (attributes.getLength()>0) {
for (int i=0; i<attributes.getLength(); i++) {
System.out.print(attributes.getLocalName(i)+": "+attributes.getValue(i));
}
}
System.out.println();
tab++;
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
tab--;
tabulation();
System.out.println(localName);
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String content= new String(ch, start, length);
content= content.replaceAll("[\t\n]", "").trim();
if (!content.equals("")) {
tabulation();
System.out.println(content);
}
}
I'm passing in an XML file and a handler to the SAXParser but I'm getting this error:
The attributes for the parse method are defined as (File, DefaultHandler) which match exactly, so I'm not sure where I'm going wrong. Here is the full method:
public String readXML (File readFile) throws Exception {
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxFactory.newSAXParser();
final String outputString = "";
DefaultHandler handler = new DefaultHandler() {
boolean bArtist = false;
boolean bAlbumName = false;
boolean bYear = false;
boolean bGenre = false;
public void startElement(String uri, String localName, String qName, Attributes attr)
throws SAXException {
if (qName.equalsIgnoreCase("ARTIST")) { bArtist = true; }
if (qName.equalsIgnoreCase("ALBUMNAME")) { bAlbumName = true; }
if (qName.equalsIgnoreCase("YEAR")) { bYear = true; }
if (qName.equalsIgnoreCase("GENRE")) { bGenre = true; }
}
public void characters(char ch[], int start, int length) {
if (bArtist) {
outputString.concat("Artist: " + new String(ch,start,length) + "\n");
}
if(bAlbumName) {
outputString.concat("Album: " + new String(ch,start,length) + "\n");
}
if(bYear) {
outputString.concat("Year: " + new String(ch,start,length) + "\n");
}
if(bGenre) {
outputString.concat("Genre: " + new String(ch,start,length) + "\n");
}
outputString.concat("\n");
}
};
saxParser.parse(readFile,handler);
return outputString;
}
It should be org.xml.sax.helpers.DefaultHandler
not jdk.internal...
so
import org.xml.sax.helpers.DefaultHandler;
You should probably also define the class that extends the DefaultHandler not just inline it.
I saw an example in mykong - http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
I tried to make it work for the xml file (below) by making the following modifications to the code in the above page -
1 - Have only two if blocks in startElement() and characters() methods.
2 - Change the print statements in above methods, ie
FIRSTNAME and First Name = passenger id
LASTNAME and Last Name = name
The problem is - In the output, I see the word passenger instead of the value of passenger id. How do i fix that ?
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="www.google.com">
<passenger id="001">
<name>Tom Cruise</name>
</passenger>
<passenger id="002">
<name>Tom Hanks</name>
</passenger>
</root>
Java Code
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ReadXMLFileSAX{
public static void main(String argv[]) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bfname = false;
boolean blname = false;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("passenger id")) {
bfname = true;
}
if (qName.equalsIgnoreCase("name")) {
blname = true;
}
}
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 {
if (bfname) {
System.out.println("passenger id : " + new String(ch, start, length));
bfname = false;
}
if (blname) {
System.out.println("name : " + new String(ch, start, length));
blname = false;
}
}
};
saxParser.parse("c:\\flight.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
In the startElement, when it's for "passenger", Attributes argument you get will have that value.
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("passenger") && attributes != null){
System.out.println(attributes.getValue("id"));
}
}
When i try to read the xml from java using SAX parser, it is unable to read the content in element present after special character
For ex:
<title>It's too difficult</title>
After reading using the SAX parser, it's displaying only It
How to handle special characters. My sample code is as below
package com.test.java;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ReadXMLUsingSAXParser {
public static void main(String argv[]) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
int titleCount;
boolean title = false;
boolean description = false;
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
// System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("title")) {
title = true;
titleCount+=1;
}
if (qName.equalsIgnoreCase("description")) {
description = true;
}
}
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 {
if (title&&titleCount>2) {
System.out.println("title : "
+ new String(ch, start, length)+":"+titleCount);
title = false;
}
if (description) {
System.out.println("description : "
+ new String(ch, start, length));
description = false;
}
}
};
saxParser.parse("C:\\Documents and Settings\\sukumar\\Desktop\\sample.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The characters(char ch[], int start, int length) methode does not read full lines, you should store the characters in a StringBuffer and use it in the endElemen method.
E.g.:
private StringBuffer buffer = new StringBuffer();
public void endElement(String uri, String localName,
String qName)
throws SAXException {
if (qName.equalsIgnoreCase("title")) {
System.out.println("title: " + buffer);
}else if (qName.equalsIgnoreCase("description")) {
System.out.println("description: " + buffer);
}
buffer = new StringBuffer();
}
public void characters(char ch[], int start, int length)
throws SAXException {
buffer.append(new String(ch, start, length));
}