Xml not parsing String as input with sax
Solution 1
You should replace the line saxParser.parse(xml.toString(), handler);
with the following one:
saxParser.parse(new InputSource(new StringReader(xml)), handler);
Solution 2
I'm going to highlight another issue, which you're likely to hit once you read your file correctly.
The method
public void characters(char ch[], int start, int length)
won't always give you the complete text element. It's at liberty to give you the text element (content) 'n' characters at a time. From the doc:
SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks
So you should build up your text element string from each call to this method (e.g. using a StringBuilder
) and only interpret/store that text once the corresponding endElement()
method is called.
This may not impact you now. But it'll arise at some time in the future - likely when you least expect it. I've encountered it when moving from small to large XML documents, where buffering has been able to hold the whole small document, but not the larger one.
An example (in pseudo-code):
public void startElement() {
builder.clear();
}
public void characters(char ch[], int start, int length) {
builder.append(new String(ch, start, length));
}
public void endElement() {
// no do something with the collated text
builder.toString();
}
Solution 3
Mybe this help. it's uses javax.xml.parsers.DocumentBuilder, which is easier than SAX
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
// return DOM
return doc;
}
you can loop through the document by using NodeList and check each Node by it's name
Mrical Singhal
Updated on July 09, 2022Comments
-
Mrical Singhal almost 2 years
I have a string input from which I need to extract simple information, here is the sample xml (from mkyong):
<?xml version="1.0"?> <company> <staff> <firstname>yong</firstname> <lastname>mook kim</lastname> <nickname>mkyong</nickname> <salary>100000</salary> </staff> <staff> <firstname>low</firstname> <lastname>yin fong</lastname> <nickname>fong fong</nickname> <salary>200000</salary> </staff> </company>
How I parse it within my code (I have a field
String name
in my class) :public String getNameFromXml(String xml) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { boolean firstName = false; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("firstname")) { firstName = true; } } public void characters(char ch[], int start, int length) throws SAXException { if (firstName) { name = new String(ch, start, length); System.out.println("First name is : " + name); firstName = false; } } }; saxParser.parse(xml.toString(), handler); } catch (Exception e) { e.printStackTrace(); } return name; }
I'm getting a
java.io.FileNotFoundException
and I see that it's trying to find a filemyprojectpath + the entireStringXML
What am I doing wrong?
Addon :
Here is my main method :
public static void main(String[] args) { Text tst = new Text("<?xml version=\"1.0\"?><company> <staff> <firstname>yong</firstname> <lastname>mook kim</lastname> <nickname>mkyong</nickname> <salary>100000</salary> </staff> <staff> <firstname>low</firstname> <lastname>yin fong</lastname> <nickname>fong fong</nickname> <salary>200000</salary> </staff></company>"); NameFilter cc = new NameFilter(); String result = cc.getNameFromXml(tst); System.out.println(result); }
-
Mrical Singhal about 12 years+1 for the though, can you give an example of how to do it in the
endElement()
please. thank you. I feel this is important what you are talking about -
Mrical Singhal about 12 yearsthanks for the response, is this correct? justpaste.it/12w3 did you mean this (I added the endelement)
-
Brian Agnew about 12 years@Gandalf - I can't get access to that site for the moment. Perhaps someone else can check ?
-
Russ Bateman almost 9 yearsThis isn't fool-proof since it's valid XML to encounter additional XML elements--with their own text characters--while parsing. In other words, you could see startElement(), characters(), startElement(), characters(), endElement(), more characters(), before reaching endElement(). Or worse than this. So, keep a stack of builder buffers. If you know your data won't exhibit that, however, you don't have to worry about it.