Parsing XML attributes from Complex Empty Elements - java

I have an xml file in the following pattern which contains a few Complex Empty Elements(elements with no content, only attributes).
<items>
<item id="0" name="a" />
<item id="1" name="b" />
</items>
I'm at lose to parse the attributes from them. This is what I have done so far :
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
Element itemsElement = document.getDocumentElement();
if (itemsElement.getTagName().equals(TAG_ITEMS)) {
NodeList nodeList = itemsElement.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
// process each item node
Node node = nodeList.item(i);
if (node.getNodeType() == Node.TEXT_NODE) { // Is this the right way?
Text text = (Text) node;
// Do stuff with attributes
}
}
}
I cannot cast these Text nodes to Element nodes and get attributes, I cannot get attributes from node using getAttributes - NPE at NamedNodeMap attributes.getLength(), I cannot cast it to Text and get attributes. How can I parse the attributes?

You are not interested in the text context of the nodes inside of items but in the attributes of the nodes item. you could proceed as follow:
//process each item node
Node node = nodeList.item(i);
if (node.getNodeName().equals("item")) {
NamedNodeMap attributes = node.getAttributes();
System.out.printf("id=%s, name=%s%n",
attributes.getNamedItem("id").getTextContent(),
attributes.getNamedItem("name").getTextContent());
}
This would print:
id=0, name=a
id=1, name=b

Assuming you want to get the indiviudal attributes of the nodes you need to one of two things (or both depending on your needs)...
You need to test if the current node is an ELEMENT_NODE or if the current node's name is equal to item (assuming all the node names are the same), for example...
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
public class Test {
public static final String TAG_ITEMS = "items";
public static void main(String[] args) {
try (InputStream is = Test.class.getResourceAsStream("/Test.xml")) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
Element itemsElement = document.getDocumentElement();
if (itemsElement.getTagName().equals(TAG_ITEMS)) {
NodeList nodeList = itemsElement.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
NamedNodeMap attributes = node.getAttributes();
Node idAtt = attributes.getNamedItem("id");
Node nameAtt = attributes.getNamedItem("name");
System.out.println("id = " + idAtt.getNodeValue());
System.out.println("name = " + nameAtt.getNodeValue());
}
}
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
Which will output...
id = 0
name = a
id = 1
name = b
All of this could be greatly reduced by using XPath, for example, if all the item nodes are the same name, then you could just use
/items/item
As the query. If the node names are different, but the attributes are the same, then you could use
/items/*[#id]
which will list all the nodes under items which has an id attribute, or
/items/*[#name]
which will list all the nodes under items which has an name attribute...
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Test {
public static void main(String[] args) {
try (InputStream is = Test.class.getResourceAsStream("/Test.xml")) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xpath.compile("/items/item");
NodeList nodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
process(nodes);
expression = xpath.compile("/items/*[#id]");
nodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
process(nodes);
expression = xpath.compile("/items/*[#name]");
nodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
process(nodes);
} catch (Exception exp) {
exp.printStackTrace();
}
}
protected static void process(NodeList nodes) {
for (int index = 0; index < nodes.getLength(); index++) {
Node item = nodes.item(index);
NamedNodeMap attributes = item.getAttributes();
Node idAtt = attributes.getNamedItem("id");
Node nameAtt = attributes.getNamedItem("name");
System.out.println("id = " + idAtt.getNodeValue() + "; name = " + nameAtt.getNodeValue());
}
}
}

Related

Java - Delete child node from dynamic XML

I want to delete a XML node that contains a PDF in Base64. This is an example:
<?xml version="1.0" encoding="UTF-8"?>
<getResult>
<id>null</id>
<pdf>ioje98fh23fjkiwf72322342</pdf>
</getResult>
First, I transform the XML in String to Document but the result is null. This is my code:
DocumentBuilder dbf = null;
Document doc = null;
try {
dbf = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader("<getResult><id>null</id><pdf>ioje98fh23fjkiwf72322342</pdf></getResult>"));
doc = dbf.parse(is);
NodeList children = doc. getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node currentChild = children.item(i);
System.out.println(currentChild);
}
} catch (Exception e) {
System.out.println(e.getMessage().toString());
}
The result is always: [getResult: null]
Considering that the main node can vary but the structure does not, How can I get the PDF node?
Here is the could you could use to retrieve the data.
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.w3c.dom.CharacterData;
public class LabFour {
public static void main(String[] args) {
DocumentBuilder dbf = null;
Document doc = null;
try {
dbf = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(
new StringReader("<getResult><id>null</id><pdf>ioje98fh23fjkiwf72322342</pdf></getResult>"));
doc = dbf.parse(is);
NodeList nodes = doc.getElementsByTagName("getResult");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("id");
Element line = (Element) name.item(0);
System.out.println("id: " + getCharacterDataFromElement(line));
NodeList pdf = element.getElementsByTagName("pdf");
line = (Element) title.item(0);
System.out.println("pdf: " + getCharacterDataFromElement(pdf));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "?";
}
}
SimpleXml can do it:
final SimpleXml simple = new SimpleXml();
final Element element = simple.fromXml(data);
element.children.remove(1);
System.out.println(simple.domToXml(element));
Will output:
<getResult><id>null</id></getResult>
From maven central:
<dependency>
<groupId>com.github.codemonstur</groupId>
<artifactId>simplexml</artifactId>
<version>1.4.0</version>
</dependency>

How to print child tag name of select parent tag using Single Java Method?

I need to print Child tag name of select parent tag using Java Method. In this given below Xml File. I am going select a parent tag subject and I am going to print each and every child and SubChild Tag inside subject parent tag.Example: div,p,LiberaryBook,p,p,textfile,textfile,textfile. 2. And it should print the text inside p tag which contain textfile tag
1. How to print the child tag name from select parent tag? and print the How to print text inside p tag which contain textfile tag?
<parent>
<Body class="student" id="181_student_method_3">
<Book class="Book_In_School_11" id="181_student_method_11"/>
<subject class="subject_information " id="181_student_subject_12"/>
<div class="div_passage " id="181_div_method_3">
<p class=" p_book_name" id="181_paragraph_13">
Best Java
<LiberaryBook class="Liberary" id="181_Liberary_9" >
<span class="p_span_name" id="181_span_13">Hello</span>
</LiberaryBook>
Java Program
</p>
<p class=" p_book_name" id="181_paragraph_13">
World
</p>
<p class="p_book_name" id="181_paragraph_14">
<textfile class="choice" id="C_10">Java.</textfile>
<textfile class="choice" id="C_11">
Find out how you rate against top coders.
</textfile>
<textfile class="choice3 " id="choice_12">
Unlock awesome startup jobs and hacker deals.
</textfile>
<textfile class="choice4 " id="choice_13">
User Id friends.
</textfile>
</p>
</div>
</subject>
</Body>
</parent>
private static void deleteElement(Document someNode) {
NodeList parentNode = someNode.getElementsByTagName("hottextInteraction").item(0).getChildNodes();
int parentNodeContentSize = parentNode.getLength();
for (int i = 0; i < parentNodeContentSize; i++) {
Node parentNodeitem = parentNode.item(i);
System.out.println("ChildList"+((Node) parentNodeitem.getChildNodes()).getNodeName());
NamedNodeMap attributes = parentNodeitem.getAttributes();
String attributeInParent = attributes != null ? (attributes
.getNamedItem("class") != null ? attributes.getNamedItem(
"class").getNodeValue().trim() : null) : null;
if (attributeInParent != null && attributeInParent.equals("div_passage")) {
NodeList stemContent = parentNodeitem.getChildNodes();
for(int j=0;j<stemContent.getLength();j++){
Node stem = stemContent.item(j);
if(stem instanceof Element && (stem.getNodeName().equals("p"))){
NodeList parentNode1 = someNode.getElementsByTagName("p");//First try.item(0).getChildNodes();
int parentNodeContentSize1 = parentNode1.getLength();
System.out.println(parentNodeContentSize1);
for (int i1 = 0; i1 < parentNodeContentSize1;) {
Node node = parentNode1.item(i1);
if (node instanceof Element) {
Element childElement = (Element) node;
System.out.println("tag name: " + childElement.getTagName());
}i1++;
System.out.println("Sub Child Tag:"+node.getFirstChild().getNodeName());*/
}
}
}
}
}
}
Please Check with this code to get Child Tag name and get it's text content inside P tag
package com.video.convertor;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Hottext {
public static void main(String[] args) {
String filePath = "/Users/myXml/check/test.xml";
File xmlFile = new File(filePath);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
//Element root = doc.getDocumentElement();
System.out.println(deleteElement(doc));
doc.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/Users/myXml/DEMO4.xml"));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
System.out.println("XML file updated successfully");
} catch (SAXException | ParserConfigurationException | IOException | TransformerException e1) {
e1.printStackTrace();
}
}
private static String deleteElement(Document someNode) {
String contents = "";
NodeList itemBody = someNode.getElementsByTagName("subject").item(0).getChildNodes();
int itemBodyContentSize = itemBody.getLength();
for (int i = 0; i < itemBodyContentSize; i++) {
Node passage = itemBody.item(i);
NamedNodeMap attributes = passage.getAttributes();
String selectText = attributes != null ? (attributes
.getNamedItem("class") != null ? attributes.getNamedItem(
"class").getNodeValue() : null) : null;
if (selectText != null && selectText.toString().trim().equals("div_passage")) {
NodeList pasageElements = passage.getChildNodes();
int length = pasageElements.getLength();
boolean isPassageContent = false;
for(int j=0;j<length;j++){
Node passageContent = pasageElements.item(j);
if(passageContent instanceof Element && (passageContent.getNodeName().equals("p"))){
if(isPassageContent){
NodeList p = pasageElements.item(j).getChildNodes();
for (int k = 0;k < p.getLength(); k++){
Node noded = p.item(k);
if (noded.getNodeType() == Node.ELEMENT_NODE) {
if(noded.getNodeName() != null && (noded.getNodeName().equals("textfile"))){
contents = contents+p.item(k).getTextContent()+"\n";
}
}
}
}else{
isPassageContent = true;
}
}
}
}
}return contents;
}
}

Parsing XML using java DOM

Im new in Java, and i have a task to Parse one xml file using http with current url http://belbooner.site40.net/testXmls/details.xml
I created Some class to parse it using Dom method, but im having java.lang.NullPointerException while trying to get one Nodes value
So here's the code
import java.security.KeyStore.Builder;
import java.util.*;
import java.io.*;
import java.net.*;
import javax.swing.text.Document;
import javax.xml.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.*;
import org.w3c.dom.CharacterData;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class RequestResponse {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
RequestResponse req= new RequestResponse();
req.getHTTPXml(url);
}
void getHTTPXml(URL url) throws ParserConfigurationException, IOException, SAXException {
//URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT","application/xml");
InputStream xml = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(xml);
System.out.println(document);
String doctype = conn.getContentType();
System.out.print(doctype);
NodeList root = document.getChildNodes();
Node server = getNodes("server",root);
Node check = getNodes("check", server.getChildNodes());
NodeList nodes = check.getChildNodes();
String checkid= getNodeValue("checkid", nodes);
System.out.println(checkid);
conn.disconnect();
//return (Document) DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xml);
}
Node getNodes(String tagName, NodeList nodes) {
for(int i=0; i< nodes.getLength();i++) {
Node node= nodes.item(i);
if(node.getNodeName().equalsIgnoreCase(tagName)) {
return node;
}
}
return null;
}
String getNodeValue(String tagName, NodeList nodes ) {
for ( int i = 0; i < nodes.getLength(); i++ ) {
Node node = nodes.item(i);
if (node.getNodeName().equalsIgnoreCase(tagName)) {
NodeList childNodes = node.getChildNodes();
for (int y = 0; y < childNodes.getLength(); y++ ) {
Node data = childNodes.item(y);
if ( data.getNodeType() == Node.TEXT_NODE ) {
return data.getNodeValue();
}
if(data instanceof CharacterData) {
CharacterData cd= (CharacterData) data;
return cd.getData();
}
}
}
}
return "";
}
}
The stacktrace I'm getting is the following:
application/xmlException in thread "main" java.lang.NullPointerException at
RequestResponse.getHTTPXml(RequestResponse.java:45) at
RequestResponse.main(RequestResponse.java:22)
After changin Node server = getNodes("server",root); to `
Node resultNode = getNodes("result", root);
Node server = getNodes("server", resultNode.getChildNodes());`
`application/xmlException in thread "main" java.lang.NullPointerException
at RequestResponse.getHTTPXml(RequestResponse.java:49)
at RequestResponse.main(RequestResponse.java:22)
`
Please help me to find the issue.
The problem is that Node server = getNodes("server",root); is returning null.
Why does this happen? Well look how you implemented getNodes
Node getNodes(String tagName, NodeList nodes) {
for(int i=0; i< nodes.getLength();i++) {
Node node= nodes.item(i);
if(node.getNodeName().equalsIgnoreCase(tagName)) {
return node;
}
}
return null;
}
You are giving as input the document root which is a single "Result" node, you iterate through it and you compare if the node's name is in this case "server" which never will be, hence you return null and get a NPE.
Your node look up must be done in the following way:
NodeList root = document.getChildNodes();
// Keep in mind that you have the following structure:
// result
// server
// checks
// check
// checkId
// check
// checkId
Node resultNode = getNodes("result", root);
Node server = getNodes("server", resultNode.getChildNodes());
Node checks = getNodes("checks", server.getChildNodes());
NodeList childNodes = checks.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node possibleCheck = childNodes.item(i);
if (possibleCheck.getNodeName().equals("check")) {
String checkid = getNodeValue("checkid", possibleCheck.getChildNodes());
System.out.println(checkid);
}
}
This way you'll be iterating through the correct node list.
Using XPath is more efficient and flexible (than normal iteration) while parsing xml.
XPath Tutorial from IBM
XPath Reference Orielly tutorial
Xpath Reference Oracle java tutorial
Try below code.
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class RequestResponse {
public static void main(String[] args) throws ParserConfigurationException,
IOException, SAXException {
URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
RequestResponse req = new RequestResponse();
req.getHTTPXml(url);
}
void getHTTPXml(URL url) throws ParserConfigurationException, IOException,
SAXException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT", "application/xml");
InputStream xml = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(xml);
System.out.println(document);
String doctype = conn.getContentType();
System.out.println(doctype);
XPathFactory pathFactory = XPathFactory.newInstance();
XPath path = pathFactory.newXPath();
XPathExpression expression;
try {
expression = path.compile("/result/server/checks/check/checkid");
NodeList nodeList = (NodeList) expression.evaluate(document,
XPathConstants.NODESET);
String checkids[] = getNodeValue(nodeList);
for (String checkid : checkids) {
System.out.print(checkid + ", ");
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
conn.disconnect();
}
String[] getNodeValue(NodeList nodes) {
String checkIds[] = new String[nodes.getLength()];
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
checkIds[i] = node.getTextContent();
}
return checkIds;
}
}

Checking if particular node exists in Xml file using Xpath

I would like to check is code = "ABC" exists in my xml file using xPath.Can you please suggest me some methods for it?
<metadata>
<codes class = "class1">
<code code = "ABC">
<detail "blah blah"/>
</code>
</codes>
<codes class = "class2">
<code code = "123">
<detail "blah blah"/>
</code>
</codes>
</metadata>
[EDIT]
I did following. It reuturns null.
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xPath.compile("//codes/code[# code ='ABC']");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("nodes: "+ nodes.item(i).getNodeValue());
}
I don't know how you tested your code because <detail "blah blah"/> is an incorrect xml construct it should be <detail x="blah blah"/> i.e. a name-value pair !!
For the XPath Expression "//codes/code[# code ='ABC']" the nodes.item(i).getNodeValue()) is going to be null because it will return an Element. See the below Javadoc comment:
A working sample:
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class Test
{
public static void main(String[] args) throws Exception
{
Document doc = getDoc();
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xPath.compile("//codes/code[#code ='ABC']");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
System.out.println("Have I found anything? " + (nodes.getLength() > 0 ? "Yes": "No"));
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("nodes: "+ nodes.item(i).getNodeValue());
}
}
private static Document getDoc()
{
String xml = "<metadata>"+
"<codes class = 'class1'>"+
"<code code='ABC'>"+
"<detail x='blah blah'/>"+
"</code>"+
"</codes>"+
"<codes class = 'class2'>"+
"<code code = '123'>"+
"<detail x='blah blah'/>"+
"</code>"+
"</codes>"+
"</metadata>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(new ByteArrayInputStream(xml.getBytes()));
return dom;
}catch(Exception pce) {
pce.printStackTrace();
}
return null;
}
}

Why is this java code not parsing my Xml correctly?

I've written class to parse some xml into an object and it's not working correctly, when I try and get the value of a node I get a null rather than the contents of the node.
Here is a simplified version of my class that just does the xml parsing of a single node:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XmlReaderCutDown {
private static Logger logger = Logger.getLogger(CtiButtonsXmlReader.class);
public static void testXml(String confFile){
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(confFile));
doc.getDocumentElement().normalize();
if (logger.isDebugEnabled()){
logger.debug("The root element is " + doc.getDocumentElement().getNodeName());
}
NodeList rows = doc.getElementsByTagName("row");
NodeList topRowButtons = ((Element)rows.item(0)).getElementsByTagName("button");
logger.debug("Top row has " +topRowButtons.getLength() + " items.");
Node buttonNode = topRowButtons.item(0);
NodeList nodeList = ((Element)buttonNode).getElementsByTagName("id");
logger.debug("Node list count for "+ "id" + " = " + nodeList.getLength());
Element element = (Element)nodeList.item(0);
String xx = element.getNodeValue();
logger.debug(xx);
String elementValue = ((Node)element).getNodeValue();
if (elementValue != null) {
elementValue = elementValue.trim();
}
else {
logger.debug("Value was null");
}
logger.debug("Node id = "+ elementValue);
} catch (ParserConfigurationException e) {
logger.fatal(e.toString(),e);
} catch (SAXException e) {
logger.fatal(e.toString(),e);
} catch (IOException e) {
logger.fatal(e.toString(),e);
} catch (Exception e) {
logger.fatal(e.toString(),e);
}
}
public static void main(String[] args){
DOMConfigurator.configure("log4j.xml");
testXml("test.xml");
}
}
And here is a stripped down version of my xml file:
<?xml version="1.0"?>
<root>
<row>
<button>
<id>this is an id</id>
<action>action</action>
<image-src>../images/img.png</image-src>
<alt-text>alt txt</alt-text>
<tool-tip>Tool tip</tool-tip>
</button>
</row>
</root>
This is what the logging statments output:
DEBUG XmlReaderCutDown - The root element is root
DEBUG XmlReaderCutDown - Top row has 1 items.
DEBUG XmlReaderCutDown - Node list count for id = 1
DEBUG XmlReaderCutDown -
DEBUG XmlReaderCutDown - Value was null
DEBUG XmlReaderCutDown - Node id = null
Why isn't it getting the text in the xml node?
I'm running using JDK 1.6_10
Because the element you get is the parent element of the text one, containing the text you need. To access the text of this element, you shall use getTextContent instead of getNodeValue.
For more information, see the table in the Node javadoc.
See http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Node.html . Element.getNodeValue() always returns null. You should use Element.getTextContent()
Consider using XPath as an alternative to manually walking nodes:
public static void testXml(String confFile)
throws XPathExpressionException {
XPathFactory xpFactory = XPathFactory.newInstance();
XPath xpath = xpFactory.newXPath();
NodeList rows = (NodeList) xpath.evaluate("root/row",
new InputSource(confFile), XPathConstants.NODESET);
for (int i = 0; i < rows.getLength(); i++) {
Node row = rows.item(i);
String id = xpath.evaluate("button/id", row);
System.out.println("id=" + id);
}
}
public static void main(String[] args)
throws XPathExpressionException {
testXml("test.xml");
}

Categories

Resources