Parse XML in Java with data next to attribute - java

I need to get the value of certain XML objects in Java, but they are in the attribute tag. I'm not sure how to go about this.
XML Example:
<node id="359832" version="5" timestamp="2008-05-20T15:20:46Z" uid="4499" changeset="486842" lat="50.9051565" lon="6.963755">
<tag k="amenity" v="restaurant"/>
<tag k="name" v="Campus"/>
</node>
<node id="451153" version="4" timestamp="2009-09-17T18:09:14Z" uid="508" changeset="2514480" lat="51.6020306" lon="-0.1935029">
<tag k="amenity" v="restaurant"/>
<tag k="created_by" v="JOSM"/>
<tag k="name" v="Sun and Sea"/>
</node>
I need to get the value of lat and lon, which are inside of the <node> in addition to the value of <tag k="name" v="Sun and Sea"/>, and with each set of this, do something with it.
Pseudocode:
foreach(node in xmlFile)
{
String name = this.name;
double lat = this.lat;
double lon = this.lon;
//my own thing here
}
I have looked, but am unable to find anything on how to get the values for lat and lon, since they are next to the attribute instead of nested. I don't need to use an input-stream, the xml file is small enough that I cant store it in memory.

package com.sandbox;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
public class Sandbox {
public static void main(String argv[]) throws IOException, SAXException, ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(Sandbox.class.getResourceAsStream("/foo.xml"));
NodeList nodeNodeList = document.getElementsByTagName("node");
for (int i = 0; i < nodeNodeList.getLength(); i++) {
Node nNode = nodeNodeList.item(i);
System.out.println(nNode.getAttributes().getNamedItem("lat").getNodeValue());
System.out.println(nNode.getAttributes().getNamedItem("lon").getNodeValue());
}
}
}
This printed out:
50.9051565
6.963755
51.6020306
-0.1935029

Related

How I need to get tag name of sub child in xml by comparing the attribute value and given string value using Java?

I have a xml file. I need to get the sub child tag of the parent tag (Body) in xml file using Java. First I need to use DOM for reading an element
and get xml file from my local machine drive. I have one String varaible (Sring getSubChildValue = "181_paragraph_13") and I need to compare the value
with each and every attribute Value in the Xml file. If the given Value may be in sub child tag,I cont able to get a Value.
what I need to do for compare the String variable and with Xml File
What I need to do for print the Tag name if the String value is equal to any attrinbute Value.
Example: (P) Tag is the sub child of Tag (Body) which contain the given String Value. So I need to get tag name P.
How to avoid the Hard coding the sub-child Name to get the solution?
Example XML file:
<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=" paragraph_book_name" id="181_paragraph_13">
<LiberaryBook class="Liberary" id="181_Liberary_9" >
<Liberary class="choice "
id="Liberary_replace_1" Uninversity="University_Liberary_1">
Dubliners</Liberary>
<Liberary class="choice "
id="Liberary_replace_2" Uninversity="University_Liberary_2">
Adventure if sherlock Holmes</Liberary>
<Liberary class="choice "
id="Liberary_replace_3" Uninversity="University_Liberary_3">
Charlotte’s Web</Liberary>
<Liberary class="choice "
id="Liberary_replace_4" Uninversity="University_Liberary_4">
The Outsiders</Liberary>
</LiberaryBook>
</p>
</div>
</Body>
</parent>
Example Java code:
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 PerfectTagChange {
public static void main(String[] args) {
String filePath = "/xmlfile/Xml/check/sample.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();
changeValue(root,doc);
doc.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/xmlfile/Xml/check/Demo.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();
}
}
//This Method is used to check which attribute contain given string Value : Hard code parent tag, But no other tag.
private static void changeValue(Node someNode,Document doc) {
Sring getSubChildValue = "181_paragraph_13"
NodeList childs = someNode.getChildNodes();
for (int in = 0; in < childs.getLength();) {
Node child = childs.item(in);
if (child.getNodeType() == Document.ELEMENT_NODE) {
if (child.getNodeName().equalsIgnoreCase("Body") ) {
//If I hard code the ID here on getNamedItem("id"),
If the attribute Name got Changed from ID to Name
it will be in problem.
//3.What is the solution for solving the problem.
if(child.getAtrribute.getNamedItem("id").getNodeValue().equals(getSubChildValue)){
system.out.println(child.getAtrribute.getNamedItem("id").getNodeValue());
}
}
}
}
}
If you change your code to this:
private static void changeValue(Node someNode, Document doc, String searchString) throws Exception {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xPath.evaluate("//*[#*=\"" + searchString + "\"]",
doc.getDocumentElement(),
XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("Tagname: " + nodes.item(i).getNodeName());
}
}
you don't have the name of the attribute to be hardcoded.
EDIT:
Added searchString as parameter.

Setting attribute without prefix using Java DOM

Using Java DOM I'm trying to set an attribute for an element without the namespace before the attribute name.
So, what I need is:
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
If I try to set the attribute as following element1.setAttributeNS("http://www.myschema.com", "attr1", value); I get an empty xmlns tag and additionaly a xmlns with prefix like the following:
<element1 attr1="value" xmlns="" xmlns:ns3="http://www.myschema.com">foo</element1>
If I try to set the attribute as following element1.setAttribute("xmlns:attr1", value); I get a prefix (xmlns) before my attribute name as shown here:
<element1 xmlns:attr1="value">foo</element1>
As for further information I create my elements as following:
Element element = dom.createElementNS("http://www.myschema.com", elemName);
element.appendChild(dom.createCDATASection("foo");
xmlElement.appendChild(element);
Let's look at your desired output again:
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
In this document, the following statements are true:
documentObject and element1 are in the http://www.myschema.com namespace.
The attribute attr1 is not in any namespace.
While elements whose names are not prefixed are going to be in whatever default namespace is in effect, attributes whose names are not prefixed are not in any namespaces. See the spec:
Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.
So to obtain the output you desire, you should be able to just do:
element1.setAttribute("attr1", value);
Of course this all depends on the desired output being correct. If really attr1 must be in a namespace, then your desired output is incorrect.
Below code will produce output
<?xml version="1.0" encoding="UTF-8"?>
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
Java Code
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XMLTest {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element element = doc.createElementNS("http://www.myschema.com", "documentObject");
doc.appendChild(element);
Element element1 = doc.createElement("element1");
element.appendChild(element1);
element1.appendChild(doc.createTextNode("foo"));
Attr attr = doc.createAttribute("attr1");
attr.setValue("value");
element1.setAttributeNode(attr);
element.appendChild(element1);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("testfile.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
}
}

Accessing values using XML keyname

I have XML similar to this contained in a Document object (org.w3c.dom.Document) in my code:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<key keyname="info"> </key>
<key keyname="name"/>
<key keyname="address"/>
<key keyname="id">13</key>
</root>
I would like to be able to access each key node and print out its value, and be able to print out each value with its corresponding keyname
I have never worked with XML using keyname before, how do I access these values?
It's very simple using DOM parser using getAttributes().getNamedItem("keyname") method.
sample code:
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;
public class SpringXMLParser {
public static void parse(String file) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
Document doc = docBuilder.parse(new FileInputStream(file));
Element root = doc.getDocumentElement();
org.w3c.dom.NodeList nodeList = root.getElementsByTagName("key");
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.print(((Node) nodeList.item(i))
.getAttributes().getNamedItem("keyname"));
System.out.println("\tvalue: "+((Node) nodeList.item(i)).getTextContent());
}
}
public static void main(String args[]) throws Exception {
parse("resources/xml5.xml");
}
}
output:
keyname="info" value:
keyname="name" value:
keyname="address" value:
keyname="id" value: 13

XML filtering using getelementsbytagname

I'm trying to parse a xml file using the below program but wondering why the getFirstChild() is blank while printing...
The nodelist contains all the employee nodes and I am processing each node and trying to get the firstchild and lastchild..
xml file:
<?xml version="1.0"?>
<Employees>
<Employee emplid="1111" type="admin">
<firstname>John</firstname>
<lastname>Watson</lastname>
<age>30</age>
<email>johnwatson#sh.com</email>
</Employee>
<Employee emplid="2222" type="admin">
<firstname>Sherlock</firstname>
<lastname>Homes</lastname>
<age>32</age>
<email>sherlock#sh.com</email>
</Employee>
</Employees>
java program:
package XML;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class XMLTest {
/**
* #param args
*/
public static void main(String[] args) {
DocumentBuilderFactory builderfactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = builderfactory.newDocumentBuilder();
Document xmldocument = builder.parse(new FileInputStream(new File("c:/employees.xml")));
NodeList node = xmldocument.getElementsByTagName("Employee");
System.out.println("node length="+node.getLength());
for (int temp = 0; temp < node.getLength(); temp++){
System.out.println("First Child = " +node.item(temp).getFirstChild().getNodeValue());
System.out.println("Last Child = " +node.item(temp).getLastChild().getNodeValue());
}
} catch (ParserConfigurationException | SAXException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It's most likely due to the whitespace (spaces, tabs, line breaks etc.) that comes through as text nodes in the list as well as the elements.
When working with java's XML DOM I tend to write a helper like this as it's pretty tedious.
The DocumentBuilderFactory controls the handling of whitespaces try:
builderFactory.setIgnoringElementContentWhitespace(true);
Hope it helps!

Retrieving XML node names

I am trying to retrieve the names of all the nodes from XML file using "node.getNodeName()". While doing so, every node name is preceeded and followed by "#text". Because of that, i am not getting the exact count of nodes as well. I want "#text" to be eliminated while retrieving the names. How do i do that??
With that :
package com.hum;
import java.io.InputStreamReader;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
*
* #author herve
*/
public class PrintNameXML
{
public static void main(String[] args) throws Exception
{
String xml = "<a><o><u>ok</u></o></a>";
Document doc =
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new InputSource(new StringReader(xml)));
NodeList nl = doc.getElementsByTagName("*");
for (int i = 0; i < nl.getLength(); i++)
{
System.out.println("name is : "+nl.item(i).getNodeName());
}
}
}
I get :
name is : a
name is : o
name is : u
Is that you search ?

Categories

Resources