Using SaxParser to get an ID - java

I'm currently trying to make a java file that can do an export with xml. The only thing I need to actually retrieve is the staff id's and nothing else.If my xml file looks like this:
<? xml version= "1.0" ?>
< company>
< staff id = "22" >
< firstname> kate </firstname >
< lastname> kim </lastname >
< nickname> lolo </nickname >
< salary> 10560</ salary >
</ staff>
< staff>
< firstname> Chelsea </firstname >
< lastname> young</ lastname >
< nickname> cheloung </nickname >
< salary> 200700</ salary >
</ staff>
< staff id = "23" >
< firstname> Dani </firstname >
< lastname> Heil </lastname >
< nickname> Heily </nickname >
< salary> 300000</ salary >
</ staff>
</ company>
and my java code looks like this:
package xmlfunctions;
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 saxParser {
public static void main(String argv[]) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bfname = false;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("FIRSTNAME")) {
bfname = 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("First Name : " + new String(ch, start, length));
bfname = false;
}
}
};
saxParser.parse("KatesFile.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
How can I change it to get it to display the staff id only? That is all I really want not the other tags. Can anyone help please? I'm very unsure as to how to get the id's on their own.

You can get the value of id in startElement(), using the parameter attributes.
public void startElement(String uri, String localName,String qName,Attributes attributes) throws SAXException {
if (qName.equals("staff")) {
System.out.println(attributes.getValue("id"));
}
}
If there is no id in <staff>, the value is null.

Related

Move XML namespaces declarations to the root element

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.

reading xml file using sax parser problems

i need to read this xml file using sax parser , but the problem is beacuse of the same child node name in different nodes. This is the file:
<MasterData>
<node1>200000</node1>
<Location>
<oa:Code>88</oa:Code>
<oa:Description languageID="en-us">addres1</oa:Description>
<oa:Description languageID="ar-ae">addres2</oa:Description>
</Location>
<address>
<oa:Code>55</oa:Code>
<oa:Description languageID="en-us">Loc1</oa:Description>
<oa:Description languageID="ar-ae">Loc2</oa:Description>
</address>
</MasterData>
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyHandler2 extends DefaultHandler {
private MasterData masterdata= null;
private IssueAuthority issueAuth = null ;
private List<IssueAuthority> issueAuthList = null ;
public MasterData getMasterData() {
return masterdata;
}
boolean bmaster = false ;
boolean bLiceNum = false;
boolean bissueAuth = false ;
boolean bautCode = false ;
boolean bautDescAr = false ;
boolean bautDescEn = false ;
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("MasterData")) {
//initialize Employee object and set id attribute
masterdata = new MasterData();
System.out.println("MasterData");
}else if (qName.equalsIgnoreCase("LicenseNumber")) {
bLiceNum = true;
System.out.println("qName"+qName);
}else if (qName.equalsIgnoreCase("IssueAuthority")) {
bissueAuth = true;
}else if (qName.equalsIgnoreCase("oa:Code")) {
bautCode = true;
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("IssueAuthority")) {
issueAuthList = new ArrayList<IssueAuthority>() ;
issueAuthList.add(issueAuth) ;
}
if (qName.equalsIgnoreCase("MasterData")) {
//add Employee object to list
masterdata.setIssueAuthority(issueAuthList);
}
}
#Override
public void characters(char ch[], int start, int length) throws SAXException {
if (bLiceNum) {
masterdata.setLicenseNumber(new String(ch, start, length));
bLiceNum = false;
} else if (bissueAuth) {
issueAuth = new IssueAuthority();
bissueAuth = false ;
}else if(bautCode){
issueAuth.setCode(Integer.parseInt(new String(ch, start, length)));
bautCode = false ;
}
}
}
this my handler class
You can differentiate between the location & adress Description child nodes by flagging the entry & exit on the parent. Like that you know exactly in which element you child list you are when accessing the text on the child nodes.
The code snippet below illustrates this:
List<String> locationDescriptions = new ArrayList<String>();
List<String> addressDescriptions = new ArrayList<String>();
boolean insideAddress = false ;
boolean insideLocation = false ;
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
...
if (qName.equalsIgnoreCase("Location")) {
insideLocation = true;
}
if (qName.equalsIgnoreCase("address")) {
insideAddress = true;
}
...
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
...
if (qName.equalsIgnoreCase("Location")) {
insideLocation = false;
}
if (qName.equalsIgnoreCase("address")) {
insideAddress = false;
}
...
}
#Override
public void characters(char ch[], int start, int length) throws SAXException {
..
if (insideLocation && (bautDescAr || bautDescEn) {
locationDescriptions.add(new String(ch, start, length));
}
if (insideAddress && (bautDescAr || bautDescEn) {
addressDescriptions.add(new String(ch, start, length));
}
...
}

Android: get HTML text from XML

I have implemented in my app reading a XML. It works fine. But I want to format the text. I've tried in the XML:
<monumento>
<horarios><b>L-V:</b> 10 a 20<br/>S-D: 11 a 15</horarios>
<tarifas>4000</tarifas>
</monumento>
But the only thing I get if I put HTML character is that the text does not display in my app.
I'll have many xml so that I will not always know where to place <b>, <br/>...
How I can do?
Main
StringBuilder builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getHorarios());
}
horario2.setText(builder.toString());
builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getTarifas());
}
tarifa2.setText(builder.toString());
XMLReader
public void get() {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setContentHandler(this);
InputStream inputStream = new URL(URL + monumento + ".xml").openStream();
reader.parse(new InputSource(inputStream));
} catch (Exception e) {
}
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currTag = true;
currTagVal = "";
if (localName.equals("monumento")) {
post = new HorariosTarifasObj();
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currTag = false;
if(localName.equalsIgnoreCase("horarios")) {
post.setHorarios(currTagVal);
} else if(localName.equalsIgnoreCase("tarifas")) {
post.setTarifas(currTagVal);
} else if (localName.equalsIgnoreCase("monumento")) {
posts.add(post);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currTag) {
currTagVal = currTagVal + new String(ch, start, length);
currTag = false;
}
}
Try CDATA:
<monumento>
<horarios><![CDATA[<b>L-V:</b> 10 a 20<br/>S-D: 11 a 15]]></horarios>
<tarifas>4000</tarifas>
</monumento>
In XML, < and > characters are reserved for XML tags. You will need to protect them by replacing them with special encoding characters.
You can use > for > and < for <
(edit) Eomm answer is right, CDATA does this as well, and more simple
Also, to use HTML coding in TextView, you will need to use Html.fromHtml() method
For instance :
tarifa2.setText(Html.fromHtml(builder.toString()));

Error in output of a simple SAX parser

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"));
}
}

Unable to read special characters from xml using java

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));
}

Categories

Resources