This question already has answers here:
Getting document as null [#document: null] After parsing XML in java using DocumentBuilder
(2 answers)
Closed 3 years ago.
I want to convert XML string into Document in java. the code is below..
package org.com;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class MainPage {
public static void main(String[] args)
{
final String xmlStr = "<employees>" +
" <employee id=\"101\">" +
" <name>Lokesh Gupta</name>" +
" <title>Author</title>" +
" </employee>" +
" <employee id=\"102\">" +
" <name>Brian Lara</name>" +
" <title>Cricketer</title>" +
" </employee>" +
"</employees>";
//Use method to convert XML string content to XML Document object
Document doc = convertStringToXMLDocument( xmlStr);
doc.getDocumentElement().normalize();
//Verify XML document is build correctly
System.out.println(doc.getFirstChild().getNodeName());
}
private static Document convertStringToXMLDocument(String xmlString)
{
//Parser that produces DOM object trees from XML content
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//API to obtain DOM Document instance
DocumentBuilder builder;
try
{
//Create DocumentBuilder with default configuration
builder = factory.newDocumentBuilder();
//Parse the content to Document object
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
return doc;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
But when i am trying to debug this code then Document is showing null like this.. [#document: null].
Here question is that how to convert XML string into only in Document object without using Nodelist to read child node one by one.
I referred this Example
Please help..
Thanks in advance
1,my example use jdom
2,like this code
final String xmlStr = "<employees>" +
" <employee id=\"101\">" +
" <name>Lokesh Gupta</name>" +
" <title>Author</title>" +
" </employee>" +
" <employee id=\"102\">" +
" <name>Brian Lara</name>" +
" <title>Cricketer</title>" +
" </employee>" +
"</employees>";
StringReader stringReader = new StringReader(xmlStr);
SAXBuilder builder = new SAXBuilder();
Document build = builder.build(stringReader);
Element rootElement = build.getRootElement();
List employee = rootElement.getChildren();
for (int i = 0; i < employee.size(); i++) {
Element emp = (Element) employee.get(i);
String id = emp.getAttributeValue("id");
String name = emp.getChildText("name");
String title = emp.getChildText("title");
System.out.printf("id: %s,name: %s, title : %s", id, name, title);
System.out.println();
}
Related
I did some codes but they are not working. I also need to validate if a header:message exists
String xml = "<header:HostError>
<header:message>
<header:messageCode>321</header:messageCode>
<header:message>test</header:message>
</header:message>
<header:message>
<header:messageCode>123</header:messageCode>
<header:message>test</header:message>
</header:message>
</header:HostError>"
How do I get the first messageCode and message?
private void extractErrorsFromResponse(SOAPFaultDetail faultResponse) {
for (Iterator itr = faultResponse.getAllDetailEntries(); itr.hasNext(); ) {
Object element = itr.next();
if (element instanceof OMElement) {
Object code = ((OMElement) element).getFirstChildWithName(new QName("message")).getFirstChildWithName(new QName("messageCode"));
Object message = ((OMElement) element).getFirstChildWithName(new QName("message")).getFirstChildWithName(new QName("message"));
faultResponse.addDetailEntry(((OMElement) element).cloneOMElement());
}
}
}
A quick solution would be that.
String xml = "<header:HostError>" +
"<header:message>\n" +
"<header:messageCode>321</header:messageCode>\n" +
"<header:message>test</header:message>\n" +
"</header:message>\n" +
"<header:message>\n" +
"<header:messageCode>123</header:messageCode>\n" +
"<header:message>test</header:message>\n" +
"</header:message>\n" +
"</header:HostError>";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));
NodeList list = doc.getElementsByTagName("header:messageCode");
System.out.println("First messageCode : " + list.item(0).getFirstChild().getNodeValue());
NodeList list_ = doc.getElementsByTagName("header:message");
System.out.println("First message : " + list_.item(1).getFirstChild().getNodeValue());
It prints,
First messageCode : 321
First message : test
Based on that, you need to find a more generic method.
I have a XML format stored in a String variable. It's like this,
String xml = "myXML";
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
In above XML you can see there are multiple ITEMS. Can somebody tell using a loop or something,How can i store each Item in a arrayList or something? I would love if i can give it a try, But unfortunately i don't have an idea how to do it.
Appreciate if someone could help?
Please note that the XML is stored in the string variable as a String.
You can parse XML pretty easily in Java.
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import java.io.StringReader;
//...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(YOUR_XML_STRING));
Document xml = builder.parse(is);
Element root = xml.getDocumentElement();
Node node = root.getFirstChild();
while(node != null) {
//Browse nodes
node = node.getNextSibling();
}
} catch (ParserConfigurationException | SAXException | IOException e) {
Logger.getGlobal().log(Level.SEVERE, "Couldn't load config", e);
}
Note that you can also search by id or tag name for example :
xml.getElementsByTagName("item"); //Returns a NodeList
Read the doc for more information.
You can create an ArrayList of items like below code :
import java.io.StringReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
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;
public class Lab {
public static Map<String,List<String>> hMap = new LinkedHashMap<>();
public static void main(String r[]) {
// your xml string
String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"\r\n" +
"<shiporder orderid=\"889923\"\r\n" +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" +
"xsi:noNamespaceSchemaLocation=\"shiporder.xsd\">\r\n" +
" <orderperson>John Smith</orderperson>\r\n" +
" <shipto>\r\n" +
" <name>Ola Nordmann</name>\r\n" +
" <address>Langgt 23</address>\r\n" +
" <city>4000 Stavanger</city>\r\n" +
" <country>Norway</country>\r\n" +
" </shipto>\r\n" +
" <item>\r\n" +
" <title>Empire Burlesque</title>\r\n" +
" <note>Special Edition</note>\r\n" +
" <quantity>1</quantity>\r\n" +
" <price>10.90</price>\r\n" +
" </item>\r\n" +
" <item>\r\n" +
" <title>Hide your heart</title>\r\n" +
" <quantity>1</quantity>\r\n" +
" <price>9.90</price>\r\n" +
" </item>\r\n" +
"</shiporder>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(s));
Document doc = builder.parse(is);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
for (int parameter = 0; parameter < nodeList.getLength(); parameter++) {
List<String> items = new ArrayList<>();
Node node = nodeList.item(parameter);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) node;
String title = eElement.getElementsByTagName("title").item(0).getTextContent();
String quantity = eElement.getElementsByTagName("quantity").item(0).getTextContent();
String price = eElement.getElementsByTagName("price").item(0).getTextContent();
items.add(title);
items.add(quantity);
items.add(price);
hMap.put("item" + parameter, items);
}
}
} catch (Exception e) {
e.printStackTrace();
}
hMap.forEach((h,k) -> {
System.out.println(h + ":" + k); // you can get values like hMap.get("item0") and next hMap.get("item1") etc.
});
}
}
Hope that helps you.
I have only collected common elements of item.
Hope that helps you:)
I'm just starting out with learning how to process/parse XML data in Java. I'm getting the error, "The method getNodeType() is undefined for the type NodeList" on the line, after my for-loop, that contains:
if (n.getNodeType() == Node.ELEMENT_NODE){
The type of error seems like I forgot to import something, but I believe I got everything. I am using an XML example from microsoft, in the following link:
http://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx
Thanks in advance.
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
public class Files {
public static void main (String [] args) throws IOException, ParserConfigurationException{
String address = "/home/leo/workspace/Test/Files/src/file.xml";
File xmlFile = new File(address);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = factory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
System.out.println(doc.getDocumentElement().getNodeName());
NodeList n = doc.getElementsByTagName("book id");
for (int temp = 0; temp < n.getLength(); temp++){
System.out.println(n.item(temp));
if (n.getNodeType() == Node.ELEMENT_NODE){
Element e = (Element) n;
System.out.println("author : " + e.getAttribute("author"));
System.out.println("title : " + e.getAttribute("title") );
System.out.println("genre : " + e.getAttribute("genre"));
System.out.println("price : " + e.getAttribute("price"));
System.out.println("publish_date : " + e.getAttribute("publish_date"));
System.out.println("description : " + e.getAttribute("description"));
}
}
}
}
You are calling getNodeType() on a NodeList object (n).
You need to call this function on a Node object. Example :
n.item(temp).getNodeType();
I'm looking for ways to read a generic xml file
Here is an example of a normal xml file
<?xml version="1.0"?>
<students>
<student>
<name>John</name>
<grade>B</grade>
<age>12</age>
</student>
<student>
<name>Mary</name>
<grade>A</grade>
<age>11</age>
</student>
<student>
<name>Simon</name>
<grade>A</grade>
<age>18</age>
</student>
</students>
and here is example of a typical xml parser that would read that code and print it out
public class XMLParser {
public void getAllUserNames(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File(fileName);
if (file.exists()) {
Document doc = db.parse(file);
Element docEle = doc.getDocumentElement();
// Print root element of the document
System.out.println("Root element of the document: "
+ docEle.getNodeName());
NodeList studentList = docEle.getElementsByTagName("student");
// Print total student elements in document
System.out
.println("Total students: " + studentList.getLength());
if (studentList != null && studentList.getLength() > 0) {
for (int i = 0; i < studentList.getLength(); i++) {
Node node = studentList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out
.println("=====================");
Element e = (Element) node;
NodeList nodeList = e.getElementsByTagName("name");
System.out.println("Name: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
nodeList = e.getElementsByTagName("grade");
System.out.println("Grade: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
nodeList = e.getElementsByTagName("age");
System.out.println("Age: "
+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue());
}
}
} else {
System.exit(1);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
XMLParser parser = new XMLParser();
parser.getAllUserNames("c:\\test.xml");
}
}
This code needs lines like this
NodeList studentList = docEle.getElementsByTagName("student");
NodeList nodeList = e.getElementsByTagName("name");
In order to work correctly.
My questions comes from how would I make that generic. Is there any way where I could read that same XML file without having to get specific elements by tagNames and yet still print it out in a view able format.
In the above example you are using Dom parser. By using Jaxb Context unmarshaller you can convert the xml to java object, then you can achive your task.
You need to have a generic function to handle.
Generic function is as follows:
/* Prints the Node Value */
public void PrintNodeValue(Element element, String tagName, String msg)
{
NodeList nodeList = element.getElementsByTagName(tagName);
System.out.println(msg + nodeList.item(0).getChildNodes().item(0).getNodeValue());
}
Function is called as below:
PrintNodeValue(e, "name", "Name: ");
PrintNodeValue(e, "grade", "Grade: ");
So I am having a lot of trouble reading this XML file:
<?xml version = "1.0" encoding = "UTF-8"?>
<!--this version of Eclipse dosn't support direct creation of XML files-->
<!-- you have to create one in notepad and then copy/paste it into Eclipse-->
<root testAttribute = "testValue">
<data>Phoebe</data>
<data>is</data>
<data>a</data>
<data>puppy!</data>
<secondElement testAttribute = "testValueAgain">
<data2>Poop</data2>
<data2>Doopy</data2>
</secondElement>
</root>
In my java file I get a NullPointerException in this one line.
Here's the code: (I'll point out where the exception occurs)
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import java.io.*;
public class Reading {
public static void main(String args[]){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("res/Test.xml"));
////////////////////GET ELEMENTS//////////////////
Element rootElement = doc.getDocumentElement();
System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
System.out.println("testAttribute for root element: "
+ rootElement.getAttribute("testAttribute"));
Element secondElement = doc.getElementById("secondElement");
System.out.println("testAttribute for second element: " +
secondElement.getAttribute("testAttribute")); //THIS IS THE LINE
NodeList list = rootElement.getElementsByTagName("data");
NodeList list2 = rootElement.getElementsByTagName("data2");
//////////////////////////////////
for(int i = 0; i < list.getLength(); i++){
Node dataNode = list.item(i);
System.out.println("list index: " + i + " data at that index: " +
dataNode.getTextContent());
}
for(int i = 0; i < list2.getLength(); i++){
Node dataNode = list2.item(i);
System.out.println("list2 index: " + i + " data at that index: " +
dataNode.getTextContent());
}
}catch(ParserConfigurationException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(SAXException e){
e.printStackTrace();
}
}
}
Can you guys check out my code and tell me what I can do to avoid the NullPointerException? I'm really frustrated right now. Thanks!
P.S. some of you guys answered about the line above the line that got the exception. The exception occurs when I try to PRINT OUT the testAttribute value in the secondaryElement element.
getElementByID is not what you think it is, thus returns null (there are no id="..." attributes).
The quick answer is that your secondElement is null. The reason is because you have no element with id="secondElement". Your code expects the document to contain something like
<myelement id="secondElement">...</myelement>