xml parsing from String - java

I am parsing a xml the data is coming from a String. i am using the following code for parsing:-
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = docBuilderFactory
.newDocumentBuilder();
docBuilder.isValidating();
ByteArrayInputStream ba= new ByteArrayInputStream(connect.content.getBytes("UTF-8"));
doc = docBuilder.parse(ba);
doc.getDocumentElement().normalize();
NodeList locationStatus = doc.getElementsByTagName("street");
for (int i = 0; i < locationStatus.getLength(); i++) {
Node locationValue = locationStatus.item(i).getChildNodes().item(0);
_node.addElement(locationValue.getNodeValue());
}
String [] nodeString = new String[_node.size()];
_node.copyInto(nodeString);
add(new LabelField(nodeString.length+""));
But this code is giving error , i dont no where the error is.
please Help me out
Thanks in advance

Use XStream or JAXB

did u tried this way?
SAXParserImpl saxparser = new SAXParserImpl();
ResponseHandler handler = new ResponseHandler();
ByteArrayInputStream stream = new ByteArrayInputStream(xmlresp.getBytes());
public class ResponseHandler extends DefaultHandler
{
public void startElement(String uri, String localName,
String qName,Attributes attributes) {}
public void characters(char[] ch, int start, int length)
{
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName,
String qName) throws SAXException {}
}

Related

FLAT XML of any type using SAX Parser in Java

I am a novice in Java and I have written a code in which I am struggling to fetch the element value inside the tag. for example in the below xml- id = bk001 didn't appear in the output
<book id="bk001">
<author>Hightower, Kim</author>
<title>The First Book</title>
<genre>Fiction</genre>
<price>44.95</price>
<pub_date>2000-10-01</pub_date>
<date>
<auth_date>
2000-10-01
</auth_date>
<auth_date>
2000-10-05
</auth_date>
</date>
<review>An amazing story of nothing.</review>
</book>
We can expect XML of any type, we have to convert into a flat structure e.g. CSV
Code written
public class SAX
{
Map<String, String> list = new HashMap<String,String>();
public static void main(String[] args) throws IOException {
new SAX().printElementNames("input/books_1.xml");
}
public void printElementNames(String fileName) throws IOException
{
try {
SAXParserFactory parserFact = SAXParserFactory.newInstance();
SAXParser parser = parserFact.newSAXParser();
DefaultHandler handler = new DefaultHandler()
{
public void startElement(String uri, String lName, String ele, Attributes attributes) throws SAXException {
System.out.print(ele + " ");
if((attributes.getValue("TagValue"))==null)
{
return;
}
else
{
System.out.println(attributes.getValue("TagValue"));
}
}
public void characters(char ch[], int start, int length) throws SAXException {
String value = new String(ch, start, length).trim();
if(value.length() == 0) return;
System.out.println(value);
}
};
parser.parse(new File(fileName), handler);
}catch(Exception e){
e.printStackTrace();
}
}
}
Kindly help me with the same. I have tried to search the same on stackoverflow but couldn't get anything concrete.
Agenda of the code is that it should work for any valid XML.
Note - We are not allowed to use external libraries like gson etc.
The only attribute that your code is attempting to read is "TagValue", so why would you expect your code to display the value of an "id" attribute?
replace your startElement with:
public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
System.out.print(qName + " ");
for(int i=0; i<attributes.getLength();i++) {
System.out.println(attributes.getQName(i) + " " + attributes.getValue(i));
}
}

Parse a simple xml string

I have a simple xml and want to retrieve the value held in the 'String' which is either True or False. There are lots of suggested methods which look very complex! What would be the best way to do this?
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">"True"</string>
I am able to read the xml into an xmlReader as below.
XMLReader xmlReader = SAXParserFactory.newInstance()
.newSAXParser().getXMLReader();
InputSource source = new InputSource(new StringReader(response.toString()));
xmlReader.parse(source);
How would I now get the value out of the reader?
You will first need to define a Handler :
public class MyElementHandler extends DefaultHandler {
private boolean isElementFound = false;
private String value;
public String getValue() {
return value;
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equals("elem")) {
isElementFound = true;
}
}
#Override
public void endElement(String uri, String localName, String qName) {
if (qName.equals("elem")) {
isElementFound = false;
}
}
#Override
public void characters(char ch[], int start, int length) {
if (isElementFound) {
value = new String(ch).substring(start, start + length);
}
}
}
Then, the you parse your xml as follows :
String xml = response.toString();
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
InputSource source = new InputSource(new StringReader(xml));
//-- create handlers
MyAttributeHandler handler = new MyAttributeHandler();
xmlReader.setContentHandler(handler);
xmlReader.parse(source);
System.out.println("value = " + handler.getValue());
More general question about sax parsing.
Here one does not need XML. A two-liner:
String xmlContent = response.toString();
String value = xmlContent.replaceFirst("(?sm)^.*<string[^>]*>([^<]*)<.*$", "$1");
if (value == xmlContent) { // No replace
throw new IllegalStateException("Not found");
}
boolean result = Boolean.valueOf(value.trim().toLowerCase());
With XML one could do:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(inputSource);
String xml = doc.getDocumentElement().getTextContent();

Sax parser issues in android

I'm trying to parse a xml using SAX parser. The code works fine on pc but on android the elements doesn't get added to list .
In the code i'm trying to add the data within the tags sunrise & sunset onto the list array
In public
void endElement(..) {}
System.out.println("size of list " + timeLst.size()); //Always shows 0 in android
Below is the code..
TimeServiceParser tsp = new TimeServiceParser();
tsp.parseDocument(new URL("http://www.earthtools.org/sun/47.566667/-52.716667/14/3/99/1"));
tsp.printData();
public class TimeService extends DefaultHandler {
public void parseDocument(URL sourceUrl) {
SAXParserFactory spf = SAXParserFactory.newInstance();
try{
SAXParser sp = spf.newSAXParser();
InputStream is = sourceUrl.openStream();
sp.parse(is, this);
}catch(SAXException se) {
...
}
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
tempVal = "";
if(qName.equalsIgnoreCase("sunrise")) {
tempTimeData = new TimeData();
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("sunrise")) {
tempTimeData.setSunriseTime(tempVal);
timeLst.add(tempTimeData);
}else if(qName.equalsIgnoreCase("sunset")) {
if(tempTimeData!=null) {
TimeData t = (TimeData)(timeLst.get(0));
t.setSunsetTime(tempVal);
}
}
System.out.println("size of list " + timeLst.size()); //Always shows 0 in android
}
public void characters(char[] ch, int start, int length) throws SAXException {
tempVal = new String(ch , start , length);
}
public void printData() {
Iterator<TimeData> it = timeLst.listIterator();
while(it.hasNext()) {
TimeData td = (TimeData)(it.next());
System.out.println(td.getSunriseTime());
System.out.println(td.getSunsetTime());
}
}
}

How to get content of <tagname> that contains other embedded XML tag in Java?

I have an XML document that has HTML tags included:
<chapter>
<h1>title of content</h1>
<p> my paragraph ... </p>
</chapter>
I need to get the content of <chapter> tag and my output will be:
<h1>title of content</h1>
<p> my paragraph ... </p>
My question is similar to this post: How parse XML to get one tag and save another tag inside
But I need to implement it in Java using SAX or DOM or ...?
I found a soluton using SAX in this post: SAX Parser : Retrieving HTML tags from XML but it's very buggy and doesn't work with large amounts of XML data.
Updated:
My SAX implementation:
In some situation it throw exception: java.lang.StringIndexOutOfBoundsException: String index out of range: -4029
public class MyXMLHandler extends DefaultHandler {
private boolean tagFlag = false;
private char[] temp;
String insideTag;
private int startPosition;
private int endPosition;
private String tag;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase(tag)) {
tagFlag = true;
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equalsIgnoreCase(tag)) {
insideTag = new String(temp, startPosition, endPosition - startPosition);
tagFlag = false;
}
}
public void characters(char ch[], int start, int length)
throws SAXException {
temp = ch;
if (tagFlag) {
startPosition = start;
tagFlag = false;
}
endPosition = start + length;
}
public String getInsideTag(String tag) {
this.tag = tag;
return insideTag;
}
}
Update 2: (Using StringBuilder)
I have accumulated characters by StringBuilder in this way:
public class MyXMLHandler extends DefaultHandler {
private boolean tagFlag = false;
private char[] temp;
String insideTag;
private String tag;
private StringBuilder builder;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase(tag)) {
builder = new StringBuilder();
tagFlag = true;
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equalsIgnoreCase(tag)) {
insideTag = builder.toString();
tagFlag = false;
}
}
public void characters(char ch[], int start, int length)
throws SAXException {
if (tagFlag) {
builder.append(ch, start, length);
}
}
public String getInsideTag(String tag) {
this.tag = tag;
return insideTag;
}
}
But builder.append(ch, start, length); doesn't append Start tag like<EmbeddedTag atr="..."> and </EmbeddedTag> in the Buffer. This Code print Output:
title of content
my paragraph ...
Instead of expected output:
<h1>title of content</h1>
<p> my paragraph ... </p>
Update 3:
Finally I have implemented the parser handler:
public class MyXMLHandler extends DefaultHandler {
private boolean tagFlag = false;
private String insideTag;
private String tag;
private StringBuilder builder;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase(tag)) {
builder = new StringBuilder();
tagFlag = true;
}
if (tagFlag) {
builder.append("<" + qName);
for (int i = 0; i < attributes.getLength(); i++) {
builder.append(" " + attributes.getLocalName(i) + "=\"" +
attributes.getValue(i) + "\"");
}
builder.append(">");
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (tagFlag) {
builder.append("</" + qName + ">");
}
if (qName.equalsIgnoreCase(tag)) {
insideTag = builder.toString();
tagFlag = false;
}
System.out.println("End Element :" + qName);
}
public void characters(char ch[], int start, int length)
throws SAXException {
temp = ch;
if (tagFlag) {
builder.append(ch, start, length);
}
}
public String getInsideTag(String tag) {
this.tag = tag;
return insideTag;
}
}
The problem with your code is that you try to remember the start and end positions of the string passed to you via the characters method. What you see in the exception thrown is the result of an inside tag that starts near the end of a character buffer and ends near the beginning of the next character buffer.
With sax you need to copy the characters when they are offered or the temporary buffer they occupy might be cleared when you need them.
Your best bet is not to remember the positions in the buffers, but to create a new StringBuilder in startElement and add the characters to that, then get the complete string out the builder in endElement.
Try to use Digester, I've used it years ago, version 1.5 and it were simply to create mapping for xml like you. Just simple article how to use Digester, but it is for version 1.5 and currently there is 3.0 I think last version contains a lot of new features ...

null pointer exception using SAX XML Parser

I am using the SAX Parser for XML Parsing. The problem is if I print, everything is fine. However, If I want to save anything, I get this error message (with the typos):
"XML Pasing Excpetion = java.lang.NullPointerException"
My code is given below:
Parser code:
try {
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL(
"http://50.19.125.224/Demo/VeryGoodSex_and_the_City_S6E6.xml");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler((ContentHandler) myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
Object to hold XML parsed Info:
public class ParserObject {
String name=null;
String description=null;
String bitly=null; //single
String productLink=null;//single
String productPrice=null;//single
Vector<String> price=null;
}
Handler class:
static ParserObject[] xmlDataObject = null;
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
if (qName.equalsIgnoreCase("title"))
{
xmlDataObject[index].name=currentValue;
}
else if (qName.equalsIgnoreCase("artist"))
{
xmlDataObject[index].artist=currentValue;
}
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
if (qName.equalsIgnoreCase("allinfo"))
{
System.out.println("started");
}
else if (qName.equalsIgnoreCase("tags"))
{
insideTag=1;
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
Your ParserObject array i.e xmlDataObject is having null value thats is why it is showing null pointer exception. This is my View and it might be wrong but once check it too.

Categories