Why does getLocalName() return null? - java

I'm loading some XML string like this:
Document doc = getDocumentBuilder().parse(new InputSource(new StringReader(xml)));
Later, I extract a node from this Document:
XPath xpath = getXPathFactory().newXPath();
XPathExpression expr = xpath.compile(expressionXPATH);
NodeList nodeList = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
Node node = nodeList.item(0);
Now I want to get the local name of this node but I get null.
node.getLocalName(); // return null
With the debugger, I saw that my node has the following type: DOCUMENT_POSITION_DISCONNECTED.
The Javadoc states that getLocalName() returns null for this type of node.
Why node is of type DOCUMENT_POSITION_DISCONNECTED and not ELEMENT_NODE?
How to "convert" the type of the node?

As the documentation https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Node.html#getLocalName() states:
for nodes created with a DOM Level 1 method, [...] this is always null
so make sure you use a namespace aware DocumentBuilderFactory with setNamespaceAware(true), that way the DOM is supporting the namespace aware DOM Level 2/3 and will have a non-null value for getLocalName().
A simple test program
String xml = "<root/>";
DocumentBuilderFactory db = DocumentBuilderFactory.newInstance();
Document dom1 = db.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
System.out.println(dom1.getDocumentElement().getLocalName() == null);
db.setNamespaceAware(true);
Document dom2 = db.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
System.out.println(dom2.getDocumentElement().getLocalName() == null);
outputs
true
false
so (at least) the local name problem you have is caused by using a DOM Level 1, not namespace aware document (builder factory).

Related

How to extract data from <dc> tag in java?

I am currently trying to extract the tag element < dc:title > from an epub in Java. However, i tried using
doc.getDocumentElement().getElementsByTagName("dc:title"));
and it only showed 2nd element :com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl. I would like to know how can I extract < dc:tittle > ?
Here is my code:
File fXmlFile = new File("file directory");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("1st element :" + doc.getElementsByTagName("dc");
System.out.println("2nd element :" + doc.getDocumentElement().getElementsByTagName("dc:title"));
System output:
1st element : com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl#4f53e9be
2nd element :com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl#e16e1a2
Added Sample Data
<dc:title>
<![CDATA[someData]]>
</dc:title>
<dc:creator>
<![CDATA[someData]>
</dc:creator>
<dc:language>someData</dc:language>
The method getElementsByTagName(String) is return a List of matching elements (note plural 's'). You then need to specify which element (such as by using .item(index) to access a Node instance) you want to use. Therewith, you can using getNodeValue() on that Node object.
EDITED: because of the CDATA element, rather use Node.getTextContent():
NodeList elems = doc.getElementsByTagName("dc:title");
Node item = elems.item(0);
System.out.println(item.getTextContent());
I would suggest using xpath to get the desired output.
Also, refer following link for examples.
https://www.journaldev.com/1194/java-xpath-example-tutorial
For example:
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//dc:title/text()";
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);
System.out.println(nodes.item(0).getNodeValue());

Getting a Node from XML in Java not working

I have an XML that has something like this:
<ListOfErrors>
<Error>
<ErrorCode>1</ErrorCode>
<Severity>Critical</Severity>
</Error>
<Error>
<ErrorCode>15414</ErrorCode>
<Severity>Non-Critical</Severity>
</Error>
</ListOfErrors>
I'm trying that, by receiving the error code I can retrieve the other values under the Error. For example, I receive error 1, and I get to know the severity.
I'm doing this:
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("file.xml"));
String xPathExpression = "//Error[ErrorCode=1]";
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate(xPathExpression,
document, XPathConstants.NODESET);
System.out.println(nodes.getLength());
Element firstElement = (Element)nodes.item(0);
System.out.println("Severity"+firstElement.getAttribute("Severity"));
I know it's not working, but I don't know what I am missing, the xPathExpression is working correctly because if I leave it only as //Error and I print the nodes.getlength then I get all error types.
Any help?
You're retrieving the Error node with ErrorCode = 1, but that node has no attributes, so firstElement.getAttribute("Severity") won't retrieve anything.
The Severity is actually a child node of Error, not an attribute. To get the value, you'll either need to cycle through the child nodes (firstElement.getChildNodes() ) or change the XPath to get the Severity directly ("//Error[ErrorCode=1]/Severity")

how to get a node value in Xpath - Java

I've got a section of XML that looks like this:
<entry>
<id>tag:example.com,2005:Release/343597</id>
<published>2012-04-10T11:29:19Z</published>
<updated>2012-04-10T12:04:41Z</updated>
<link type="text/html" href="http://example.com/projects/example1" rel="alternate"/>
<title>example1</title>
</entry>
I need to grab the link http://example.com/projects/example1 from this block. I'm not sure how to do this. To get the title of the project I use this code:
String title1 = children.item(9).getFirstChild().getNodeValue();
where children is the getChildNodes() object for the <entry> </entry> block. But I keep getting NullPointerExceptions when I try to get the node value for the <link> node in a similar way. I see that the XML code is different for the <link> node, and I'm not sure what it's value is.... Please advise!
The xpath expression to get that node is
//entry/link/#href
In java you can write
Document doc = ... // your XML document
XPathExpression xp = XPathFactory.newInstance().newXPath().compile("//entry/link/#href");
String href = xp.evaluate(doc);
Then if you need to get the link value of the entry with a specific id you can change the xpath expression to
//entry[id='tag:example.com,2005:Release/343597']/link/#href
Finally if you want to get all the links in the documents, if the document has many entry elements you can write
Document doc = ... // your XML document
XPathExpression xp = XPathFactory.newInstance().newXPath().compile("//entry/link/#href");
NodeList links = (NodeList) xp.evaluate(doc, XPathConstants.NODESET);
// and iterate on links
Here is the complete code:
DocumentBuilderFactory domFactory = DocumentBuilderFactory
.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("test.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("//entry/link/#href");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i));
}

Get an attribute of a dom node

I am trying to get an attribute of an xml node example:
<Car name="Test">
</Car>
I want to grab the name attribute of the car node.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(configFile);
doc.getDocumentElement().normalize();
NodeList layerConfigList = doc.getElementsByTagName("CAR");
Node node = layerConfigList.item(0);
// get the name attribute out of the node.
this is where i get stuck because the only method that looks like i can use is getAttributes() with returns a NamedNodeMap and im not sure how to extract it from that.
Your node is an Element so you just have to
Element e = (Element)node;
String name = e.getAttribute("name");
you can do it without using elements, like this:
//HtmlTag represents any arbitrary node that you are trying to get its "car" attribute
if("HtmlTag".equals(node.getNodeName()))
String nodeContent=node.getAttributes().getNamedItem("car").getNodeValue()

How to get root node attributes on java

I have an xml file like down below. I want to get pharmacies nodes' latitude and longitude attributes.I can get chilnodes attributes but couldnt get root node attributes. I am new on java and xml. I could not find a solution how to do.
<pharmacies Acc="4" latitude="36.8673380" longitude="30.6346640" address="Ayujkila">
<pharmacy name="sadde" owner="" address="dedes" distance="327.000555668" phone="342343" lat="36.8644" long="30.6345" accuracy="8"/>
<pharmacy name="Sun " owner="" address="degerse" distance="364.450016586" phone="45623" lat="36.8641" long="30.6353" accuracy="8"/>
<pharmacy name="lara" owner="" address="freacde" distance="927.262190129" phone="564667" lat="36.8731" long="30.6422" accuracy="8"
<end/>
</pharmacies>
This is my part of code. I get xml file from a url address.
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList =doc.getElementsByTagName("pharmacy");
for (int i = 0; i < nodeList.getLength(); i++){
Node node =nodeList.item(i);
Element fstElmnt = (Element) node;
NodeList pharmacyList = fstElmnt.getElementsByTagName("pharmacy");
Element pharmacyElement = (Element) pharmacyList.item(0);
Element pharmacyElement = (Element) pharmacyList.item(0);
HashMap<String,String>map=new HashMap<String,String>();
map.put("name", pharmacyElement.getAttribute("name"));
map.put("distance", pharmacyElement.getAttribute("phone"));
list.add(map);
latt.add(pharmacyElement.getAttribute("lat"));
....
The <pharmacies> element itself can be obtained using
Element pharmacies = doc.getDocumentElement();
You can get the attributes from that.
doc.getDocumentElement() will return the root element and you can call getAttribute( attrName ) on it like you would on any other element.
try the following:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
doc.getDocumentElement().normalize();
System.out.println(doc.getChildNodes().getLength());
Node item = doc.getChildNodes().item(0);
System.out.println(item.getNodeName());
Node lat = item.getAttributes().getNamedItem("latitude");
String s = lat.getNodeValue();
System.out.println(s.equals("36.8673380")); // Value of /pharmacies[#latitude]/value()
You need to use pharmacies instead of pharmacy if you need to get attributes for root node pharmacies.And use getAttributes method instead.You can see lot of examples at this site.
http://java.sun.com/developer/codesamples/xml.html#dom
Try Its Work For me, Res is your final String:
doc = b.parse(new ByteArrayInputStream(result.getBytes("UTF-8")));
Node rootNode=doc.getDocumentElement();
res = rootNode.getNodeName().toString();
The <pharmacies> is itself an element & can be obtained using
Element pharmacies = doc.getDocumentElement();
Now this pharmacies reference variable of Elements holds all the attributes under <pharmacies> element. We can get desired attributes one by one using attribute name like :
pharmacies.getAttribute("latitude"); // Will give 36.8673380
pharmacies.getAttribute("longitude"); // Will give 30.6346640

Categories