How to extract sub element as String from XML - java

I have a XML in String format:
<?xml version="1.0" encoding="UTF-8"?>
<ns4:DataRequest xmlns:ns4="urn:com:sony:xsd:DataRequest001" xmlns:ns2="urn:com:sony:xsd:pay001" xmlns:ns3="urn:com:sony:xsd:common">
<Hdr>
<Date>2021-01-28T13:29:00</Date>
<CallType>Item_Check</CallType>
<CallSubType>TFT</CallSubType>
<CallId>12345</CallId>
</Hdr>
<Pld>
<SpecData>
<MainSpec>
<AppId>123</AppId>
<Size>123</Size>
<Amt>2000</Amt>
<Payld><data><id>Id001</tag></data></Payld>
</MainSpec>
</SpecData>
</Pld>
</ns4:DataRequest>
I am extracting payld using the below code:
String payload = null;
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(new StringReader(xmlAsString));
while (reader.hasNext()) {
reader.next();
if (reader.isStartElement()) {
if ("payld".equalsIgnoreCase(reader.getLocalName())) {
payload = reader.getElementText();
break;
}
}
}
Now want to extract SpecData tag value in a string something like:
String specData = "<MainSpec><AppId>....</AppId><MainSpec>";
new to XMLStreamReader, not getting how this can be achieved.

This should work:
String specData = null;
String payload = null;
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(new StringReader(xmlAsString));
while (reader.hasNext()) {
reader.next();
if (reader.isStartElement()) {
if ("appId".equalsIgnoreCase(reader.getLocalName())) {
specData = reader.getElementText();
continue;
}
else if ("payld".equalsIgnoreCase(reader.getLocalName())) {
payload = reader.getElementText();
break;
}
}
}

Related

some suggestions for using STAX Parsing in java

I have a XML document which has at the top of it database configurations like username, password and URL and after that it has a tag called data and inside that it has data about employees and data about department that I want to pull it from the XML and insert it into a database.
I have managed to read the JDBC config and set it in a bean that return a connection and successfully worked, but now my problem is with the data tag how can I ignore the JDBC config from the XML file and read the data tag and insert it to a database, I know I can do it like
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
currentName = startElement.getName();
if(!currentName.equals("connection-setteings")) ...
But its not a good idea as I believe so can someone advice a better approach for that?
Here is the XML file:
<?xml version="1.0" encoding="UTF-8"?>
<import-request xmlns="http://www.phi01tech.com/tools/data-import" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.phi01tech.com/tools/data-import data-import.xsd ">
<connection-settings>
<username>root</username>
<password>root</password>
<url>jdbc:mysql://localhost:3306/sample</url>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
</connection-settings>
<data>
<departments dept_no="d009" dept_name="Customer Service"/>
<departments dept_no="d005" dept_name="Development"/>
<departments dept_no="d002" dept_name="Finance"/>
<departments dept_no="d003" dept_name="Human Resources"/>
<departments dept_no="d001" dept_name="Marketing"/>
<departments dept_no="d004" dept_name="Production"/>
<departments dept_no="d006" dept_name="Quality Management"/>
<departments dept_no="d008" dept_name="Research"/>
<departments dept_no="d007" dept_name="Sales"/>
<employees emp_no="10001" birth_date="1953-09-02" first_name="Georgi" last_name="Facello" gender="M"
hire_date="1986-06-26"/>
<employees emp_no="10002" birth_date="1964-06-02" first_name="Bezalel" last_name="Simmel" gender="F"
hire_date="1985-11-21"/>
<employees emp_no="10003" birth_date="1959-12-03" first_name="Parto" last_name="Bamford" gender="M"
hire_date="1986-08-28"/>
<employees emp_no="10004" birth_date="1954-05-01" first_name="Chirstian" last_name="Koblick" gender="M"
hire_date="1986-12-01"/>
<employees emp_no="10005" birth_date="1955-01-21" first_name="Kyoichi" last_name="Maliniak" gender="M"
hire_date="1989-09-12"/>
<employees emp_no="10006" birth_date="1953-04-20" first_name="Anneke" last_name="Preusig" gender="F"
hire_date="1989-06-02"/>
<employees emp_no="10007" birth_date="1957-05-23" first_name="Tzvetan" last_name="Zielinski" gender="F"
hire_date="1989-02-10"/>
<employees emp_no="10008" birth_date="1958-02-19" first_name="Saniya" last_name="Kalloufi" gender="M"
hire_date="1994-09-15"/>
</data>
</import-request>
And here is my java class:
public class STAXParser {
static ConnectionManager connectionManager = new ConnectionManager();
String currentName;
public void parseDocuments() throws IOException, XMLStreamException {
XMLInputFactory inputFactory = XMLInputFactory.newFactory();
try (InputStream stream = Files.newInputStream(Paths.get("emp.xml"))) {
XMLEventReader reader = inputFactory.createXMLEventReader(stream);
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
currentName = startElement.getName().getLocalPart();
System.out.println(startElement.getName());
Iterator attributes = startElement.getAttributes();
while(attributes.hasNext()) {
//System.out.println(attributes.next());
}
}
if (event.isCharacters()) {
if (!event.asCharacters().isWhiteSpace()) {
String data = event.asCharacters().getData();
checkName(currentName, data.trim());
}
}
}
}
}
private void checkName(String name, String event) {
if (name.equals("url"))
connectionManager.setUrl(event);
else if (name.equals("username"))
connectionManager.setUsername(event);
else if (name.equals("password"))
connectionManager.setPassword(event);
else if (name.equals("driverClassName"))
connectionManager.setDriver(event);
}
public static void main(String[] args) {
STAXParser s = new STAXParser();
try {
s.parseDocuments();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
}
try {
connectionManager.getConnection().toString();
JDBCEmployeeDao d = new JDBCEmployeeDao(connectionManager);
// d.create();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I find that XMLStreamReader is much easier to use, since elements can be processed in context of the parent, unlike XMLEventReader that returns all events in a flat sequence.
Example of parsing your XML using XMLStreamReader. For simplicity of the example, the code ignores namespaces.
public static void main(String[] args) throws Exception {
XMLInputFactory inputFactory = XMLInputFactory.newFactory();
Connection connection = null;
try (InputStream stream = Files.newInputStream(Paths.get("src/main/resources/test.xml"))) {
XMLStreamReader reader = inputFactory.createXMLStreamReader(stream);
reader.nextTag(); // Position on root tag
if (! reader.getLocalName().equals("import-request"))
throw new XMLStreamException("Invalid root element: " + reader.getLocalName());
while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
switch (reader.getLocalName()) {
case "connection-settings":
connection = parseConnectionSettings(reader);
break;
case "data":
if (connection == null)
throw new XMLStreamException("Missing <connection-settings> before <data>");
parseData(reader, connection);
break;
default:
// ignore unknown content
}
}
} finally {
if (connection != null)
connection.close();
}
}
private static Connection parseConnectionSettings(XMLStreamReader reader) throws Exception {
String username = null, password = null, url = null, driverClassName = null;
while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
switch (reader.getLocalName()) {
case "username":
username = reader.getElementText();
break;
case "password":
password = reader.getElementText();
break;
case "url":
url = reader.getElementText();
break;
case "driverClassName":
driverClassName = reader.getElementText();
break;
default:
throw new XMLStreamException("Invalid element in <connection-settings>: " + reader.getLocalName());
}
}
Class.forName(driverClassName);
return DriverManager.getConnection(url, username, password);
}
private static void parseData(XMLStreamReader reader, Connection connection) throws Exception {
while (reader.nextTag() == XMLStreamConstants.START_ELEMENT) {
switch (reader.getLocalName()) {
case "departments":
processDepartments(reader, connection);
break;
case "employees":
processEmployees(reader, connection);
break;
default:
throw new XMLStreamException("Invalid element in <data>: " + reader.getLocalName());
}
}
}
private static void processDepartments(XMLStreamReader reader, Connection connection) throws Exception {
String dept_no = reader.getAttributeValue(null, "dept_no");
String dept_name = reader.getAttributeValue(null, "dept_name");
if (! reader.getElementText().isEmpty())
throw new XMLStreamException("<departments> must be empty element");
// process here
}
private static void processEmployees(XMLStreamReader reader, Connection connection) throws Exception {
// code here
}

How to parse xml data in ArrayList [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I need to parse xml data in android. I have seen this project: here from github which teaches how to parse xml data in listbox. However, I want to get xml data to different strings. Although, I have used pretty much the same code as in the github project but I only get error and the app stops responding.
Code:
public class Main extends Fragment {
android.view.View myview;
EditText number;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myview = inflater.inflate(R.layout.fragment_screen, container, false);
number = (EditText) myview.findViewById(R.id.number);
XmlParser par = new XmlParser();
number.setText(par.getStackSitesFromFile(getActivity().getBaseContext())
.get(0).getLink()); **Error here**
return myview;
}
}
XmlParser.java
public class XmlParser {
static final String KEY_SITE = "rate";
static final String KEY_NAME = "Name";
static final String KEY_LINK = "Rate";
static final String KEY_ABOUT = "Date";
static final String KEY_IMAGE_URL = "Time";
public static List<HandleXML> getStackSitesFromFile(Context ctx) {
// List of StackSites that we will return
List<HandleXML> stackSites;
stackSites = new ArrayList<HandleXML>();
// temp holder for current StackSite while parsing
HandleXML curStackSite = null;
// temp holder for current text value while parsing
String curText = "";
try {
// Get our factory and PullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
// Open up InputStream and Reader of our file.
FileInputStream fis = ctx.openFileInput("/sdcard/rates.xml");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
// point the parser to our file.
xpp.setInput(reader);
// get initial eventType
int eventType = xpp.getEventType();
// Loop through pull events until we reach END_DOCUMENT
while (eventType != XmlPullParser.END_DOCUMENT) {
// Get the current tag
String tagname = xpp.getName();
// React to different event types appropriately
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equals("test")) {
curStackSite = new HandleXML();
}
break;
case XmlPullParser.TEXT:
//grab the current text so we can use it in END_TAG event
curText = xpp.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase("test")) {
stackSites.add(curStackSite);
} else if (tagname.equalsIgnoreCase(KEY_NAME)) {
curStackSite.setName(curText);
} else if (tagname.equals("Rate")) {
curStackSite.setLink(curText);
} else if (tagname.equalsIgnoreCase(KEY_ABOUT)) {
curStackSite.setAbout(curText);
} else if (tagname.equalsIgnoreCase(KEY_IMAGE_URL)) {
curStackSite.setImgUrl(curText);
}
break;
default:
break;
}
eventType = xpp.next();
}
} catch (Exception e) {
e.printStackTrace();
}
// return the populated list.
return stackSites;
}
}
And finally, HandleXml.java
public class HandleXML {
private String name;
private String rate;
private String date;
private String time;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLink() {
return rate;
}
public void setLink(String rate) {
this.rate = rate;
}
public String getAbout() {
return date;
}
public void setAbout(String date) {
this.date = date;
}
public String getImgUrl() {
return time;
}
public void setImgUrl(String time) {
this.time = time;
}
#Override
public String toString() {
return name + rate;
}
}
Xml File:
<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="1" yahoo:created="2016-09-07T05:50:08Z" yahoo:lang="en-US">
<results>
<test>
<Name>EUR/USD</Name>
<Rate>1.1251</Rate>
<Date>9/7/2016</Date>
<Time>0:56am</Time>
</test>
<test>
<Name>EUR/USD</Name>
<Rate>1.1253</Rate>
<Date>9/7/2016</Date>
<Time>0:56am</Time>
</test>
</results>
</query>
The error is in the first fragment of code in: number.setText(par.getStackSitesFromFile(getActivity().getBaseContext()).get(0).getLink());
The arraylist returns empty because FileInputStream fis is set to open a file which contains path separator (/) , and it causes
java.lang.IllegalArgumentException: File /sdcard/rates.xml contains a path separator
. You have to use
FileInputStream fis = new FileInputStream (new File("/sdcard/rates.xml")); instead. Do not forget to close fis by fis.close();
Final code for XmlParser will be:
public class XmlParser {
static final String KEY_SITE = "rate";
static final String KEY_NAME = "Name";
static final String KEY_LINK = "Rate";
static final String KEY_ABOUT = "Date";
static final String KEY_IMAGE_URL = "Time";
FileInputStream fis;
public static List<HandleXML> getStackSitesFromFile() {
// List of StackSites that we will return
List<HandleXML> stackSites;
stackSites = new ArrayList<HandleXML>();
// temp holder for current StackSite while parsing
HandleXML curStackSite = null;
// temp holder for current text value while parsing
String curText = "";
try {
// Get our factory and PullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
// Open up InputStream and Reader of our file.
fis = new FileInputStream(new File("/sdcard/rates.xml"));
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
// point the parser to our file.
xpp.setInput(reader);
// get initial eventType
int eventType = xpp.getEventType();
// Loop through pull events until we reach END_DOCUMENT
while (eventType != XmlPullParser.END_DOCUMENT) {
// Get the current tag
String tagname = xpp.getName();
// React to different event types appropriately
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equals("test")) {
curStackSite = new HandleXML();
}
break;
case XmlPullParser.TEXT:
//grab the current text so we can use it in END_TAG event
curText = xpp.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase("test")) {
stackSites.add(curStackSite);
} else if (tagname.equalsIgnoreCase(KEY_NAME)) {
curStackSite.setName(curText);
} else if (tagname.equals("Rate")) {
curStackSite.setLink(curText);
} else if (tagname.equalsIgnoreCase(KEY_ABOUT)) {
curStackSite.setAbout(curText);
} else if (tagname.equalsIgnoreCase(KEY_IMAGE_URL)) {
curStackSite.setImgUrl(curText);
}
break;
default:
break;
}
eventType = xpp.next();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
fis.close();
}catch(Exception e){
Log.i("Problem closing", "Closing fis");
}
// return the populated list.
return stackSites;
}
}
And then set number.setText() like that: number.setText(par.getStackSitesFromFile().get(0).getLink());

Unexcepted NullPointerException RSS Reader in Java

I am trying change my RSS Reader code. I have something like this:
public class RSSFeedParser {
static final String TITLE = "title";
static final String DESCRIPTION = "description";
static final String CHANNEL = "channel";
static final String LANGUAGE = "language";
static final String COPYRIGHT = "copyright";
static final String LINK = "link";
static final String AUTHOR = "author";
static final String ITEM = "item";
static final String PUB_DATE = "pubDate";
static final String GUID = "guid";
public InputStream in = read();
private XMLInputFactory inputFactory = XMLInputFactory.newInstance();
private XMLEventReader eventReader;
final URL url;
public RSSFeedParser(String feedUrl) {
try {
url = new URL(feedUrl);
eventReader = inputFactory.createXMLEventReader(in);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Feed readFeed() {
Feed feed = null;
try {
boolean isFeedHeader = true;
String description = "";
String title = "";
String link = "";
String language = "";
String copyright = "";
String author = "";
String pubDate = "";
String guid = "";
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
String localPart = event.asStartElement().getName().getLocalPart();
switch (localPart) {
case ITEM:
if (isFeedHeader) {
isFeedHeader = false;
feed = new Feed(title, link, description, language, copyright, pubDate);
}
event = eventReader.nextEvent();
break;
case TITLE:
title = getCharacterData(event, eventReader);
break;
case DESCRIPTION:
description = getCharacterData(event, eventReader);
break;
case LINK:
link = getCharacterData(event, eventReader);
break;
case GUID:
guid = getCharacterData(event, eventReader);
break;
case LANGUAGE:
language = getCharacterData(event, eventReader);
break;
case AUTHOR:
author = getCharacterData(event, eventReader);
break;
case PUB_DATE:
pubDate = getCharacterData(event, eventReader);
break;
case COPYRIGHT:
copyright = getCharacterData(event, eventReader);
break;
}
}
else if(event.isEndElement()) {
if (event.asEndElement().getName().getLocalPart() == (ITEM)) {
FeedMessage message = new FeedMessage();
message.setAuthor(author);
message.setDescription(description);
message.setGuid(guid);
message.setLink(link);
message.setTitle(title);
feed.getMessages().add(message);
}
}
}
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
return feed;
}
private InputStream read(){
try{
return url.openStream();
}catch (IOException e){
throw new RuntimeException(e);
}
}
private String getCharacterData(XMLEvent event, XMLEventReader eventReader) throws XMLStreamException {
String results="";
event = eventReader.nextEvent();
if(event instanceof Characters){
results = event.asCharacters().getData();
}
return results;
}
And main:
public static void main(String[] args) {
RSSFeedParser parser = new RSSFeedParser("http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/other_sports/rss.xml");
Feed feed = parser.readFeed();
System.out.println(feed);
for (FeedMessage message : feed.getMessages()) {
System.out.println(message);
RSSFeedWriter writer = new RSSFeedWriter(feed, "articles.rss");
try {
writer.write();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I get NullPointerException in
public InputStream in = read();
return url.openStream();
RSSFeedParser parser = new RSSFeedParser("http://newsrss.bbc.co.uk/rss/sportonline_uk_edition/other_sports/rss.xml");
What's wrong with this code? Everything was working when the InputStream, XMLEventReader and XMLInputFactory was in separate class.
You are calling the read() method before the URL object is initialized. Try something like this:
public InputStream in;
public RSSFeedParser(String feedUrl) {
try {
url = new URL(feedUrl);
in = read();
eventReader = inputFactory.createXMLEventReader(in);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Also, It is good practice to close resources after use (streams & readers).

How do you pull XHTML out of an ATOM feed using Java?

I am trying to pull some XHTML out of an RSS feed so I can place it in a WebView. The RSS feed in question has a tag called <content> and the characters inside the content are XHTML. (The site I'm paring is a blogger feed)
What is the best way to try to pull this content? The < characters are confusing my parser. I have tried both DOM and SAX but neither can handle this very well.
Here is a sample of the XML as requested. In this case, I want basically XHTML inside the content tag to be a string. <content> XHTML </content>
Edit: based on ignyhere's suggestion I have tried XPath, but I am still having the same issue. Here is a pastebin sample of my tests.
It's not pretty, but this is (the essence of) what I use to parse an ATOM feed from Blogger using XmlPullParser. The code is pretty icky, but it is from a real app. You can probably get the general flavor of it, anyway.
final String TAG_FEED = "feed";
public int parseXml(Reader reader) {
XmlPullParserFactory factory = null;
StringBuilder out = new StringBuilder();
int entries = 0;
try {
factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(reader);
while (true) {
int eventType = xpp.next();
if (eventType == XmlPullParser.END_DOCUMENT) {
break;
} else if (eventType == XmlPullParser.START_DOCUMENT) {
out.append("Start document\n");
} else if (eventType == XmlPullParser.START_TAG) {
String tag = xpp.getName();
// out.append("Start tag " + tag + "\n");
if (TAG_FEED.equalsIgnoreCase(tag)) {
entries = parseFeed(xpp);
}
} else if (eventType == XmlPullParser.END_TAG) {
// out.append("End tag " + xpp.getName() + "\n");
} else if (eventType == XmlPullParser.TEXT) {
// out.append("Text " + xpp.getText() + "\n");
}
}
out.append("End document\n");
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return out.toString();
return entries;
}
private int parseFeed(XmlPullParser xpp) throws XmlPullParserException, IOException {
int depth = xpp.getDepth();
assert (depth == 1);
int eventType;
int entries = 0;
xpp.require(XmlPullParser.START_TAG, null, TAG_FEED);
while (((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT) && (xpp.getDepth() > depth)) {
// loop invariant: At this point, the parser is not sitting on
// end-of-document, and is at a level deeper than where it started.
if (eventType == XmlPullParser.START_TAG) {
String tag = xpp.getName();
// Log.d("parseFeed", "Start tag: " + tag); // Uncomment to debug
if (FeedEntry.TAG_ENTRY.equalsIgnoreCase(tag)) {
FeedEntry feedEntry = new FeedEntry(xpp);
feedEntry.persist(this);
entries++;
// Log.d("FeedEntry", feedEntry.title); // Uncomment to debug
// xpp.require(XmlPullParser.END_TAG, null, tag);
}
}
}
assert (depth == 1);
return entries;
}
class FeedEntry {
String id;
String published;
String updated;
// Timestamp lastRead;
String title;
String subtitle;
String authorName;
int contentType;
String content;
String preview;
String origLink;
String thumbnailUri;
// Media media;
static final String TAG_ENTRY = "entry";
static final String TAG_ENTRY_ID = "id";
static final String TAG_TITLE = "title";
static final String TAG_SUBTITLE = "subtitle";
static final String TAG_UPDATED = "updated";
static final String TAG_PUBLISHED = "published";
static final String TAG_AUTHOR = "author";
static final String TAG_CONTENT = "content";
static final String TAG_TYPE = "type";
static final String TAG_ORIG_LINK = "origLink";
static final String TAG_THUMBNAIL = "thumbnail";
static final String ATTRIBUTE_URL = "url";
/**
* Create a FeedEntry by pulling its bits out of an XML Pull Parser. Side effect: Advances
* XmlPullParser.
*
* #param xpp
*/
public FeedEntry(XmlPullParser xpp) {
int eventType;
int depth = xpp.getDepth();
assert (depth == 2);
try {
xpp.require(XmlPullParser.START_TAG, null, TAG_ENTRY);
while (((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT)
&& (xpp.getDepth() > depth)) {
if (eventType == XmlPullParser.START_TAG) {
String tag = xpp.getName();
if (TAG_ENTRY_ID.equalsIgnoreCase(tag)) {
id = Util.XmlPullTag(xpp, TAG_ENTRY_ID);
} else if (TAG_TITLE.equalsIgnoreCase(tag)) {
title = Util.XmlPullTag(xpp, TAG_TITLE);
} else if (TAG_SUBTITLE.equalsIgnoreCase(tag)) {
subtitle = Util.XmlPullTag(xpp, TAG_SUBTITLE);
} else if (TAG_UPDATED.equalsIgnoreCase(tag)) {
updated = Util.XmlPullTag(xpp, TAG_UPDATED);
} else if (TAG_PUBLISHED.equalsIgnoreCase(tag)) {
published = Util.XmlPullTag(xpp, TAG_PUBLISHED);
} else if (TAG_CONTENT.equalsIgnoreCase(tag)) {
int attributeCount = xpp.getAttributeCount();
for (int i = 0; i < attributeCount; i++) {
String attributeName = xpp.getAttributeName(i);
if (attributeName.equalsIgnoreCase(TAG_TYPE)) {
String attributeValue = xpp.getAttributeValue(i);
if (attributeValue
.equalsIgnoreCase(FeedReaderContract.FeedEntry.ATTRIBUTE_NAME_HTML)) {
contentType = FeedReaderContract.FeedEntry.CONTENT_TYPE_HTML;
} else if (attributeValue
.equalsIgnoreCase(FeedReaderContract.FeedEntry.ATTRIBUTE_NAME_XHTML)) {
contentType = FeedReaderContract.FeedEntry.CONTENT_TYPE_XHTML;
} else {
contentType = FeedReaderContract.FeedEntry.CONTENT_TYPE_TEXT;
}
break;
}
}
content = Util.XmlPullTag(xpp, TAG_CONTENT);
extractPreview();
} else if (TAG_AUTHOR.equalsIgnoreCase(tag)) {
// Skip author for now -- it is complicated
int authorDepth = xpp.getDepth();
assert (authorDepth == 3);
xpp.require(XmlPullParser.START_TAG, null, TAG_AUTHOR);
while (((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT)
&& (xpp.getDepth() > authorDepth)) {
}
assert (xpp.getDepth() == 3);
xpp.require(XmlPullParser.END_TAG, null, TAG_AUTHOR);
} else if (TAG_ORIG_LINK.equalsIgnoreCase(tag)) {
origLink = Util.XmlPullTag(xpp, TAG_ORIG_LINK);
} else if (TAG_THUMBNAIL.equalsIgnoreCase(tag)) {
thumbnailUri = Util.XmlPullAttribute(xpp, tag, null, ATTRIBUTE_URL);
} else {
#SuppressWarnings("unused")
String throwAway = Util.XmlPullTag(xpp, tag);
}
}
} // while
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
assert (xpp.getDepth() == 2);
}
}
public static String XmlPullTag(XmlPullParser xpp, String tag)
throws XmlPullParserException, IOException {
xpp.require(XmlPullParser.START_TAG, null, tag);
String itemText = xpp.nextText();
if (xpp.getEventType() != XmlPullParser.END_TAG) {
xpp.nextTag();
}
xpp.require(XmlPullParser.END_TAG, null, tag);
return itemText;
}
public static String XmlPullAttribute(XmlPullParser xpp,
String tag, String namespace, String name)
throws XmlPullParserException, IOException {
assert (!TextUtils.isEmpty(tag));
assert (!TextUtils.isEmpty(name));
xpp.require(XmlPullParser.START_TAG, null, tag);
String itemText = xpp.getAttributeValue(namespace, name);
if (xpp.getEventType() != XmlPullParser.END_TAG) {
xpp.nextTag();
}
xpp.require(XmlPullParser.END_TAG, null, tag);
return itemText;
}
I'll give you a hint: None of the return values matter. The data is saved into a database by a method (not shown) called at this line:
feedEntry.persist(this);
I would attempt to attack it with XPath. Would something like this work?
public static String parseAtom (InputStream atomIS)
throws Exception {
// Below should yield the second content block
String xpathString = "(//*[starts-with(name(),"content")])[2]";
// or, String xpathString = "//*[name() = 'content'][2]";
// remove the '[2]' to get all content tags or get the count,
// if needed, and then target specific blocks
//String xpathString = "count(//*[starts-with(name(),"content")])";
// note the evaluate expression below returns a glob and not a node set
XPathFactory xpf = XPathFactory.newInstance ();
XPath xpath = xpf.newXPath ();
XPathExpression xpathCompiled = xpath.compile (xpathString);
// use the first to recast and evaluate as NodeList
//Object atomOut = xpathCompiled.evaluate (
// new InputSource (atomIS), XPathConstants.NODESET);
String atomOut = xpathCompiled.evaluate (
new InputSource (atomIS), XPathConstants.STRING);
System.out.println (atomOut);
return atomOut;
}
I can see your problem here, the reason why these parsers are not producing the correct result is because contents of your <content> tag are not wrapped into <![CDATA[ ]]>, what I would do until I find more adequate solution I'd use quick and dirty trick :
private void parseFile(String fileName) throws IOException {
String line;
BufferedReader br = new BufferedReader(new FileReader(new File(fileName)));
StringBuilder sb = new StringBuilder();
boolean match = false;
while ((line = br.readLine()) != null) {
if(line.contains("<content")){
sb.append(line);
sb.append("\n");
match = true;
continue;
}
if(match){
sb.append(line);
sb.append("\n");
match = false;
}
if(line.contains("</content")){
sb.append(line);
sb.append("\n");
}
}
System.out.println(sb.toString());
}
This will give you all content in String. You can optionaly seperate them by slightly modyfiying this method or if you don't need actual <content> you can filter that out as well.

xml parsing+Java ME

I am editing my qestion to make clear idea about the string name resfile_name and result
I want to do xml parsing.where i am passing some parameter to url ane it gives me responce in xml format which i take it in string name result now i want to parse that string(xml data).
i am using the follwing below code:-
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
vector = new Vector();
vector.addElement(new KeyPair("ParentID", "10000186"));
String result = Constants.callSoap("GetChildList", vector);
InputStream is = new ByteArrayInputStream(result.getBytes("UTF-8"));
Reader reader = new InputStreamReader(in);
XmlParser parser = new XmlParser(reader);
ParseEvent pe = null;
Reader reader = new InputStreamReader(in);
XmlParser parser = new XmlParser(reader);
ParseEvent pe = null;
parser.skip();
parser.read(Xml.START_TAG, null, "GetChildListResult");
parser.skip();
parser.read(Xml.START_TAG, null, "CustomChildList");
boolean trucking = true;
boolean first = true;
while (trucking) {
pe = parser.read();
if (pe.getType() == Xml.START_TAG) {
String name = pe.getName();
System.out.println("nAME=="+name);
if (name.equals("ChildID")) {
String title, link, description;
title = link = description = null;
while ((pe.getType() != Xml.END_TAG) ||
(pe.getName().equals(name) == false)) {
pe = parser.read();
if (pe.getType() == Xml.START_TAG &&
pe.getName().equals("ChildName")) {
pe = parser.read();
title = pe.getText();
}
else if (pe.getType() == Xml.START_TAG &&
pe.getName().equals("IMEINumber")) {
pe = parser.read();
link = pe.getText();
}
else if (pe.getType() == Xml.START_TAG &&
pe.getName().equals("ChildStatus")) {
pe = parser.read();
description = pe.getText();
}
}
}
else {
while ((pe.getType() != Xml.END_TAG) ||
(pe.getName().equals(name) == false))
pe = parser.read();
}
}
if (pe.getType() == Xml.END_TAG &&
pe.getName().equals("GetChildListResult"))
trucking = false;
}
the Constants.callSoap("GetChildList", vector); calls the callsoap method in constants which has code:--
public static String callSoap(String method, Vector vector) {
String result = null;
Constants.log("callSoap");
try {
SoapObject request = new SoapObject(NAMESPACE, method);
if (vector != null) {
for (int i = 0; i < vector.size(); i++) {
KeyPair keyPair = (KeyPair) vector.elementAt(i);
request.addProperty(keyPair.getKey(), keyPair.getValue());
}
}
Constants.log("callSoap2");
Element[] header = new Element[1];
header[0] = new Element().createElement(NAMESPACE, "AuthSoapHd");
Element username = new Element().createElement(NAMESPACE, "strUserName");
username.addChild(Node.TEXT, "*****");
header[0].addChild(Node.ELEMENT, username);
Element password = new Element().createElement(NAMESPACE, "strPassword");
password.addChild(Node.TEXT, "******");
header[0].addChild(Node.ELEMENT, password);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.headerOut = header;
envelope.setOutputSoapObject(request);
Constants.log("callSoap3");
HttpTransport transport = new HttpTransport("http://***.***.*.***/ChildTrackerService/ChildTrackerService.asmx?wsdl");
//log("Log:transport");
transport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
//log("Log:transport1");
try {
transport.call("http://tempuri.org/" + method, envelope);
//log("Log:transport:call");
result = (envelope.getResponse()).toString();
} catch (Exception e) {
System.out.println("exception of IP==" + e);
}
} catch (Exception e) {
log("Exception CallSoap:" + e.toString());
}
return result;
}
And the class keypair contain:-
public KeyPair(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
The string reult has --
result==anyType{CustomChildList=anyType{ChildID=452; ChildName=Local; IMEINumber=958694; ChildStatus=Free; ExpiryDate=2011-05-26T16:22:21.29; RemainigDays=1; SOS=1; }; CustomChildList=anyType{ChildID=502; ChildName=testing; IMEINumber=123456; ChildStatus=anyType{}; ExpiryDate=null; RemainigDays=0; SOS=1; }; CustomChildList=anyType{ChildID=523; ChildName=abc; IMEINumber=124124; ChildStatus=anyType{}; ExpiryDate=null; RemainigDays=0; SOS=1; }; }
the actual response is like this:--
452
Local
958694
Free
2011-05-26T16:22:21.29
1
1
502
testing
123456
0
1
523
abc
124124
0
1
Following code will look for resources in classpath with the name passed in argument and you are passing whole XML so NPE is obvious.
this.getClass().getResourceAsStream(resfile_name)
You better get the inputStream from URL , as shown in below broken snippet and move ahead
HttpConnection hc = null;
try {
hc = (HttpConnection)Connector.open(url);
parse(hc.openInputStream());
See
Parsing XML in java-me

Categories

Resources