I'm trying to parse an XML file. The format of the XML file is:
<Testcase>
<Title>Low Load</Title>
<MO_Call>DIAL</MO_Call>
<Delay>10</Delay>
<MO_Call>HANGUP</MO_Call>
<Delay>10</Delay>
<MO_SMS>SEND</MO_SMS>
</Testcase>
I need to get the key-value pairs under the node "Testcase" and store in a datastructure. Ordering is important, and hence I'm considering a LinkedHashMap.
Please suggest the right way to get the key-value pairs from the XMl file.
In the above XML snippet, the corresponnding key-value pairs are:
Key: MO_Call, Value: DIAL
Key: Delay, Value: 10
I have written the below code for parsing the XML:
try {
builder = factory.newDocumentBuilder();
Document doc = builder.parse(new FileInputStream(CONFIG_PATH));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName(TAG_TEST_CASE);
if (nodeList != null && nodeList.getLength() > 0) {
for (int i=0; i < nodeList.getLength(); i++) {
Element el = (Element) nodeList.item(i);
// If title doesn't match, check the next title under next 'Testcase' NodeList
if(el.getFirstChild().getNodeName().equals(TAG_TITLE) &&
!el.getFirstChild().getNodeValue().equals(title)) {
continue;
}
// else, title matches. So parse the child nodes.
// Start from index 1, since index 0 is title always
NodeList childNodeList = el.getChildNodes();
for(int j=1; j < childNodeList.getLength(); j++) {
Node childNode = childNodeList.item(j);
//Element childElement = (Element) childNodeList.item(j);
Log.d("Tool", "key=" +childNode.getNodeName()+ ", value=" +childNode.getTextContent());
}
}
}
}
I'm getting the output:
key=Title, value=Low Load
key=#text, value=
key=MO_Call, value=DIAL
key=#text, value=
key=Delay, value=10
key=#text, value=
key=MO_Call, value=HANGUP
key=#text, value=
key=Delay, value=10
key=#text, value=
key=MO_SMS, value=SEND
key=#text, value=
key=Title, value=Medium Load
key=#text, value=
key=Title, value=High Load
key=#text, value=
For some reason, the key "#text" is coming up along with null value. Please help me avoid this.
Please, reffer here for the #text. If you can alter the XML, remove ALL spaces that are unintentional, then re-test your code.
Example XML:
<?xml version="1.0" encoding="UTF-8"?><Testcase><Title>Low Load</Title><MO_Call>DIAL</MO_Call><Delay>10</Delay><MO_Call>HANGUP</MO_Call><Delay>10</Delay><MO_SMS>SEND</MO_SMS></Testcase>
Also, please show the encode used on the XML file, there could be typos.
This is also a good suggestion on how to parse
Related
I have one XML which look like this ::
<Channels>
<Channel Id="511" Title="Test" ChannelDescription="This is Test Channel./>
</Channels>
I am successfully parse this kind of XML.My Problem is that when i fired the webservice and if there is no authentication from the server then the webservice response like this::
<AuthenticationError>An Active Session Already Exists For This User.</AuthenticationError>
So how can i check that root node is "Authentication Error" or "Notes". And if i get the Authentication Error tag then how can i get its node value which is "An Active Session Already Exists For This User."??
Code for XML Parsing is this::
NodeList node =null;
node= (NodeList)result.getElementsByTagName("Channels");
for(int j=0;j<node.getLength();j++)
{
Node aNode=node.item(j);
Element fstElmnt = (Element) aNode;
NodeList websiteList = fstElmnt.getElementsByTagName("Channel");
int check=websiteList.getLength();
for(int k=0;k<check;k++)
{
DatabaseConstant myChannels = new DatabaseConstant();
Node checkNode=websiteList.item(k);
Element websiteElement = (Element) checkNode;
myChannels.id=websiteElement.getAttribute("Id");
myChannels.title=websiteElement.getAttribute("Title");
channel .add(myChannels);
}
}
}
I hope my question is clear... Please provide the solution asap. Thanks in Advance....
Use getDocumentElement() to get root Element, then use getTagName() to get tag name.
Example:
Element root = result.getDocumentElement();
String name = root.getTagName();
if(name.equalsIgnoreCase("AuthenticationError") )
{
String value = myDocument.getDocumentElement().getTextContent();
System.out.println("Error:" + value);
}
else if(name.equalsIgnoreCase("Notes") )
{
NodeList nodes = root.getElementsByTagName("Channels");
for(int i = 0 ; i < nodes.getLength() ; i ++)
{
//-----do something with channels nodes--
}
}
I have an xml that i am parsing through DOM parser. the xml is of somewhat this sequence
<root>
<item1> abc </item1>
<item2> def </item2>
<item3> ghi </item3>
<item4>
<subItem4>
<name> xyz </name>
<id> 1 </id>
</subItem4>
<subItem4>
<name> asd </name>
<id> 2 </id>
</subItem4>
</item4>
</root>
According to this dummy xml i am reaching till subItem 4 but not to the childern of it. what i am trying is as follows to get innermost Items is:
NodeList slide = theElement.getElementsByTagName("item4").item(0).getChildNodes();
for(int i = 0; i<slide.getLength(); i++)
{
NodeList subSlides = theElement.getElementsByTagName("subItem4").item(0).getChildNodes();
for (int j=0; j<subSlides.getLength(); j++)
{
String subSlide_title = subSlides.item(i).getFirstChild().getNodeValue();
}
}
its not working. please can someone identify where am i doing the mistake in parsing. Any help is appreciated.
You are not using valid XML - you can't have spaces in tag names.
XML Names cannot contain white space, see here for valid values.
Update (following comment that the posted sample is representative of the actual XML):
Your access via the indexer of the node list is incorrect:
String subSlide_title = subSlides.item(i).getFirstChild().getNodeValue();
Try this instead (using j instead of i, as the inner loop variable is called):
String subSlide_title = subSlides.item(j).getFirstChild().getNodeValue();
NodeList nodes = doc.getElementsByTagName("item");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList nodesimg = element.getElementsByTagName("name");
for (int j = 0; j < nodesimg.getLength(); j++) {
Element line = (Element) nodesimg.item(j);
String value=getCharacterDataFromElement(line);
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "?";
}
I think above code will help you in parsing xml file.
The XML elements are all messed up.
There are literally 2 lines that don't have mistakes in them.
For instance
<subItem 4>
is syntactically wrong and I don't see what logical sense you could make out of it.
Do you mean
<subItem4>
as in the fourth sub item or
<subItem someAttribute="4">
I'd recommend learning XML, it's very simple... http://www.w3schools.com/xml/default.asp
I have a sample XML (Android platform) and I wanted to know the easiest and most efficient approach to get the node value of the node "e". Please help.
<a>
<b>
<c>
<e>data</e>
</c>
</b>
<b>
</b>
</a>
Use XPath.
See - http://developer.android.com/reference/javax/xml/xpath/package-summary.html
The XPath expression to grab the correct element would be:
/a/b/c/e
You could coalesce the resulting node into a String to get the textual value.
I think following code will help you to extract data of "e" node.
NodeList nodes = doc.getElementsByTagName("b");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList nodesimg = element.getElementsByTagName("e");
for (int j = 0; j < nodesimg.getLength(); j++) {
Element line = (Element) nodesimg.item(j);
String value=getCharacterDataFromElement(line);
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "?";
}
Implement Pull Parser, example is given here: http://icodesnip.com/snippet/java/android-pull-parser-sample
So by your case, you have to write the condition inside the start tag for "e".
It look like this in XML. I want to get he Image src value...
<description><![CDATA[<div class="images"><img src="http://www.voicetv.co.th/cache/images/8a1a6f2aeb7b0e9c1d6bb3eae314165f.jpg" /></div>]]></description>
What I am doing is
if ((theElement.getElementsByTagName("description")).getLength() > 0) {
allChildern = theElement.getElementsByTagName("description").item(0).getChildNodes();
for (int index = 0; index < allChildern.getLength(); index++) {
description += allChildern.item(index).getNodeValue();
NodeList chNodes = allChildern.item(index).getChildNodes();
for (int i = 0; i < chNodes.getLength(); i++) {
String name = chNodes.item(i).getNodeName();
if(name.equals("div")) {
String clas = allChildern.item(index).getAttributes().getNamedItem("class").getNodeValue();
if(clas.equals("images")){
String nName = allChildern.item(index).getChildNodes().item(0).getNodeName();
if(nName.equals("img")) {
String nValue = allChildern.item(index).getChildNodes().item(0).getAttributes().getNamedItem("src").getNodeValue();
}
}
}
}
}
currentStory.setDescription(description);
}
But is is not working
The description element contains a CDATA node. This means that the <img> "element" you are trying to access is really just a piece of text (and not an element at all).
You'll need to parse the text as a new XML document in order to access it via DOM methods.
Warning: This might be a bit dirty, and it can also be fragile if the xml can contain comments that contains something that looks like image tags.
An alternative to using xml parsing for that short xml snippet that has a cdata section is to get the image url using regexp. Here's an example:
String xml = "<description><![CDATA[<div class=\"images\"><img src=\"http://www.voicetv.co.th/cache/images/8a1a6f2aeb7b0e9c1d6bb3eae314165f.jpg\"/></div>]]></description>";
Matcher matcher = Pattern.compile("<img src=\"([^\"]+)").matcher(xml);
while (matcher.find()) {
System.out.println("img url: " + matcher.group(1));
}
If I parse the tag that contains <p>Some Text</p> tag, I get a null pointer exception.
My RSS feed is as follows:
<quaddeals_conditions><p>Limit one QuadDeal</p></quaddeals_conditions>
My code is:
if (name.equalsIgnoreCase("quaddeals_conditions")) {
property.normalize();
conditions = property.getFirstChild().getNodeValue();
}
You have an element inside an element .
Therefore retrieve all quaddeals and then iterate each one and retrieve from it the p element:
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.inputStream);
Element root = dom.getDocumentElement();
// snip
NodeList items = root.getElementsByTagName("quaddeals_conditions");
for (int i = 0; i < items.getLength(); i++) {
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for (int j = 0; j < properties.getLength(); j++) {
Node property = properties.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase("p")) {
property.getFirstChild().getNodeValue(); // Your paragraph data
}
}
}
Hope this helps.
is "name" not NULL? I dont see you check for that.
It's good coding practice to compare the other way if possible:
if ("quaddeals_conditions".equalsIgnoreCase(name))...
So even if "name" is NULL, you don't get a NullPointerException.
Always check for not null before accessing some object member.