number´s of parse strings from xml - java

i have a little question :).My problem is , that i parse a xml and make by every tag there are parsing a new fragment. .But now my problem:
By creating Tabs i must give the FragmentPagerAdapter the numbers of tabs there he must creating.I downt know why i can give him they without array list.Thats the code there say how much tabs he must creating.Normaly it locks like
public final String[] titles = {"123", "123"}; but now i parse it to a string without array.
#Override
public int getCount() {
return Names.length();
}
but this isnt posible with Strings, so my question can anybody can tell me a solution on there i can give him a number of the tags from the xml there he have parse.
the xml:
<rooms>
<room>
<roomname>Wohnzimmer</roomname>
<devices>
<device>
<deviceid>1</deviceid>
<devicename>some name</devicename>
<action1>3</action1>
<action2>4</action2>
<devicetype>some name</devicetype>
<text1>1</text1>
<text2>2</text2>
</device>
</devices>
</room>
<room>
<roomname>Wohnzimmer</roomname>
<devices>
<device>
<deviceid>1</deviceid>
<devicename>some name</devicename>
<action1>3</action1>
<action2>4</action2>
<devicetype>some name</devicetype>
<text1>1</text1>
<text2>2</text2>
</device>
</devices>
</room>
</rooms>
i need the childs there are the xml parser parse from the category rooms(the childs from the tag rooms).i want to count the tags there the rooms tag have. in this case its are 2.
My code looks now so:
#Override
public int getCount() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse("employees.xml");
Element element = (Element) dom.getElementsByTagName("app_type").item(0);
NodeList nodes = dom.getElementsByTagName("tagName");
int count = nodes.getLength();
}
catch (ParserConfigurationException pce) {
pce.printStackTrace();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
catch (SAXException sae) {
sae.printStackTrace();
}
return count;
}
but i get a error on count he cant resolve count.

What I understood you have an xml and you are looking to parse few tags out of that xml, you can use XML java API
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse("employees.xml");
Element element = (Element) dom.getElementsByTagName("app_type").item(0);
NodeList nodes = dom.getElementsByTagName('"tagName");
int count = nodes.getLength();
Dont forget to put this in try catch block as this API throws exceptions.
Cheers !!

Related

How to store values in an array (Java)

I have a table (REQUESTS) and it contains 1 column (XML_DATA) for xmls.
So if ID=123 has a row in this table, it should get the corresponding xml.
If xml was retrieved, i need to get all the values with tag <Mobile>0918xxxx</Mobile>.
Here is what i have so far:
for (int i = 0; i < RqeuestsDBViewData.length; i++) //GETS ROWS FROM TABLE REQUESTS
{
xmlDetails = test.getDetailsFromXML(mCustUtils, RequestDBViewData[i]); //GETS XML FROM XML_DATA
String strXmlDetails;
String strMob;
if (!AppUtils.isEmpty(xmlDetails)) //IF IT HAS ROW, THEN GET RECORD FROM <MOBILE></MOBILE> TAG
{
strXmlDetails = xmlDetails.toString(); //ENTIRE XML
strMob = StringUtils.substringBetween(strXmlDetails, "<Mobile>", "</Mobile>"); //GETS MOBILE VALUE
}
Now, if there are more than 1 <Mobile></Mobile>,
i need to store it in an array using for loop.
How do i store multiple values of strMob in an array?
After stroring all possible strMob, i'm planning to assign the values somewhere else like: personalInfo[j].setMobile(array/list[j]);
Any suggestions on how to do this?
Use a proper XML tool to read your XML.
Variant 1
Use Jackson to parse your XML to a prepared Java object. This will also work for arrays.
Variant 2
Read XML to a DOM object
public static Element getDocument(String xmlString) {
return getDocument(new ByteArrayInputStream(xmlString.getBytes()));
}
public static Element getDocument(InputStream inputStream) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.parse(new BufferedInputStream(inputStream));
Element root = doc.getDocumentElement();
root.normalize();
return root;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
With the aim of XPATH you can than extract your <Mobile> elements. See this answer: Extract content between XML tags

Unexpected token (<) using Document builder in Android Studio

I'm using document builder and NodeList in Android Studio to parse an xml document. I previously found that the xml was incorrect and had un-escaped ampersands within the text. After taking care of this though and double check with w3 XML validator, I still get an unexpected token error:
e: "org.xml.sax.SAXParseException: Unexpected token (position:TEXT \n \n 601\n ...#5262:1 in java.io.StringReader#cd0db4a)"
However, when I open the xml and look at the line referred to, I don't see anything that would be considered troublesome:
... ...
5257 <WebSvcLocation>
5258 <Id>1521981</Id>
5259 <Name>Warehouse: Row 3</Name>
5260 <SiteName>Warehouse</SiteName>
5261 </WebSvcLocation>
5262 </ArrayOfWebSvcLocation>
I have checked the xml as well for non printing characters and I have not found any. Below is the code I have been using:
public List<Location> SpinnerXML(String xml){
List<Location> list = new ArrayList<Location>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
InputSource is;
String s = xml.replaceAll("[&]"," and ");
try {
builder = factory.newDocumentBuilder();
is = new InputSource(new StringReader(s));
Document doc = builder.parse(is);
NodeList lt = doc.getElementsByTagName("WebSvcLocation");
int id;
String name,siteName;
for (int i = 0; i < lt.getLength(); i++) {
Element el = (Element) lt.item(i);
id = Integer.parseInt(getValue(el, "Id"));
name = getValue(el, "Name");
siteName = getValue(el, "SiteName");
list.add(new Location(id, name, siteName));
}
} catch (ParserConfigurationException e){
} catch (SAXException e){
e.printStackTrace();
} catch (IOException e){
}
return list;
}
The XML I have been trying to read is hosted here.
Thanks in advance for the help!
InputSource seems to do some guessing as to the encoding, so here's some things to try.
From here it says:
Android note: The Android platform default (encoding) is always UTF-8.
Referenced from here
Java stores strings as UTF-16 internally.
"Java stores strings as UTF-16 internally, but the encoding used
externally, the "system default encoding", varies.
(1) I would initially recommend:
is.setEncoding("UTF-8");
(2) But it should do no harm to replace this:
Document doc = builder.parse(is);
With this:
Document doc = builder.parse(new ByteArrayInputStream(s.getBytes()));
(3) OR try this:
String s1 = URLDecoder.decode(s, "UTF-8");
Document doc = builder.parse(new ByteArrayInputStream(s1.getBytes()));
NOTE:
if you try (2) or (3) comment OUT:
is = new InputSource(new StringReader(s));
As it may mess up String s.

Looking for a specific child in XML using java

I've been looking for the past few hours, and I can't find how to do it.
My XML file:
<list>
<Company id="01">
<Name>Atari</Name>
<Founded>1972</Founded>
<Consoles>
2600
5200
7800
</Consoles>
</Company>
<Company id="02">
<Name>Sega</Name>
<Founded>1960</Founded>
<Consoles>
Master System
Megadrive
Saturn
</Consoles>
</Company>
</list>
Basically, I want the code to find not only the name in one company block, but the name in any company block I wish, and be able to show it to other classes. So far, I've been able to show either or, but only by changing the code directly and not on the fly. The code I'm using:
private static String getTextValue(String def, Element doc, String tag) {
String value = def;
NodeList nl;
nl = doc.getElementsByTagName(tag);
if (nl.getLength() > 0 && nl.item(0).hasChildNodes()) {
value = nl.item(0).getFirstChild().getNodeValue();
}
if(value==null) value = " ";
return value;
}
public static boolean readXML(String xml) {
rolev = new ArrayList<String>();
Document dom;
// Make an instance of the DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// use the factory to take an instance of the document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// parse using the builder to get the DOM mapping of the
// XML file
dom = db.parse(xml);
Element doc = dom.getDocumentElement();
role1 = getTextValue(role1, doc, "Name");
if (getRole1() != null) {
if (!getRole1().isEmpty())
rolev.add(getRole1());
}
role2 = getTextValue(role2, doc, "Founded");
if (role2 != null) {
if (!role2.isEmpty())
rolev.add(role2);
}
role3 = getTextValue(role3, doc, "Consoles");
if (role3 != null) {
if (!role3.isEmpty())
rolev.add(role3);
}
role4 = getTextValue(role4, doc, "Name");
if ( role4 != null) {
if (!role4.isEmpty())
rolev.add(role4);
}
return true;
} catch (ParserConfigurationException pce) {
System.out.println(pce.getMessage());
} catch (SAXException se) {
System.out.println(se.getMessage());
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
return false;
}
I used a lot of different methods, some searched up and some made on my own, but this one is the closest I can get to working for what I need. I need to be able to have the place it's looking change on the fly though.
You can use xpath to read XML. See Parsing XML with XPath in Java and/or How to read XML using XPath in Java
In your case, if you wanted to get all of the company names the set path you would use (basically the tag filter) would be "//list/Company/Name/text()"
The rest of the code can basically be copied from the questions I posted. Only your set (filter) would be different.

Retrieve XML Element names with Java from unknown message format

I am parsing XML from lots of JMS messaging topics, so the structure of each message varies a lot and I'd like to make one general tool to parse them all.
To start, all I want to do is get the element names:
<gui-action>
<action>some action</action>
<params>
<param1>blue</param1>
<param2>tall</param2>
<params>
</gui-action>
I just want to retrieve the strings "gui-action", "action", "params", "param1", and "param2." Duplicates are just fine.
I've tried using org.w3c.dom.Node, Element, NodeLists and I'm not having much luck. I keep getting the element values, not the names.
private Element root;
private Document doc;
private NodeList nl;
//messageStr is passed in elsewhere in the code
//but is a string of the full XML message.
doc = xmlParse( messageStr );
root = doc.getDocumentElement();
nl = root.getChildNodes();
int size = nl.getLength();
for (int i=0; i<size; i++) {
log.info( nl.item(i).getNodeName() );
}
public Document xmlParse( String xml ){
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
InputSource is;
try {
//Using factory get an instance of document builder
db = dbf.newDocumentBuilder();
is = new InputSource(new StringReader( xml ) );
doc = db.parse( is );
} catch(ParserConfigurationException pce) {
pce.printStackTrace();
} catch(SAXException se) {
se.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
return doc;
//parse using builder to get DOM representation of the XML file
}
My logged "parsed" XML looks like this:
#text
action
#text
params
#text
Figured it out. I was iterating over only the child nodes, and not including the parent. So now I just filter out the #texts, and include the parent. Derp.
log.info(root.getNodeName() );
for (int i=0; i<size; i++) {
nodeName = nl.item(i).getNodeName();
if( nodeName != "#text" ) {
log.info( nodeName );
}
}
Now if anyone knows a way to get a NodeList of the entire document, that would be awesome.

Parsing XML from website to an Android device

I am starting an Android application that will parse XML from the web. I've created a few Android apps but they've never involved parsing XML and I was wondering if anyone had any tips on the best way to go about it?
Here's an example:
try {
URL url = new URL(/*your xml url*/);
URLConnection conn = url.openConnection();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(conn.getInputStream());
NodeList nodes = doc.getElementsByTagName(/*tag from xml file*/);
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList title = element.getElementsByTagName(/*item within the tag*/);
Element line = (Element) title.item(0);
phoneNumberList.add(line.getTextContent());
}
}
catch (Exception e) {
e.printStackTrace();
}
In my example, my XML file looks a little like:
<numbers>
<phone>
<string name = "phonenumber1">555-555-5555</string>
</phone>
<phone>
<string name = "phonenumber2">555-555-5555</string>
</phone>
</numbers>
and I would replace /*tag from xml file*/ with "phone" and /*item within the tag*/ with "string".
I always use the w3c dom classes. I have a static helper method that I use to parse the xml data as a string and returns to me a Document object. Where you get the xml data can vary (web, file, etc) but eventually you load it as a string.
something like this...
Document document = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try
{
builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(data));
document = builder.parse(is);
}
catch (SAXException e) { }
catch (IOException e) { }
catch (ParserConfigurationException e) { }
There are different types of parsing mechanisms available, one is SAX Here is SAX parsing example, second is DOM parsing Here is DOM Parsing example.. From your question it is not clear what you want, but these may be good starting points.
There are three types of parsing I know: DOM, SAX and XMLPullParsing.
In my example here you need the URL and the parent node of the XML element.
try {
URL url = new URL("http://www.something.com/something.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList1 = doc.getElementsByTagName("parent node here");
for (int i = 0; i < nodeList1.getLength(); i++) {
Node node = nodeList1.item(i);
}
} catch(Exception e) {
}
Also try this.
I would use the DOM parser, it is not as efficient as SAX, if the XML file is not too large, as it is easier in that case.
I have made just one android App, that involved XML parsing. XML received from a SOAP web service. I used XmlPullParser. The implementation from Xml.newPullParser() had a bug where calls to nextText() did not always advance to the END_TAG as the documentation promised. There is a work around for this.

Categories