get the number of elements in an XML document - java

I need to get the total number of nodes in an xml file in java ( java dom ...)
In the file below, the total number of elements is 15
<?xml version="1.0" encoding="UTF-8"?>
<personnes>
<etudiant classe="P2">
<nom>CynO</nom>
<prenoms>
<prenom>Nicolas</prenom>
<prenom>Laurent</prenom>
</prenoms>
<age>25</age>
</etudiant>
<etudiant classe="P1">
<nom>Superwoman</nom>
<prenoms>
<prenom>Sia</prenom>
</prenoms>
<age>34</age>
</etudiant>
<etudiant classe="P3">
<nom>Don Corleone</nom>
<age>28</age>
</etudiant>
</personnes>
thank you

Try with following code snippet. It is worked for me.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class CountNoOfElements{
public static void main(String args[]) throws Exception {
String filepath = "test.xml";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
NodeList nodeList = doc.getElementsByTagName("*");
int count = nodeList.getLength();
System.out.println("Total of elements : " + count);
}
}

Related

Getting all attributes of an xml by using java and Xpath

I have the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://www.test.com/rest/v1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<child test="folder" id="2019-05-15-04.52.05.641880A01" />
<child test="folder" id="2019-05-15-04.52.05.901880A02" />
</root>
I want to read the above xml by using Java code and Xpath, retrieve the id's of the child nodes(i.e. id="2019-05-15-04.52.05.641880A01" and id="2019-05-15-04.52.05.901880A02") and store them into List. I tried with the following java code:
InputSource source = new InputSource(new StringReader(xml));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document document = db.parse(source);
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
return xpath.evaluate(expression, document);
I called the above the above method with the following Xpath along with the input xml:
*[local-name()='root']/*[local-name()='child']/#id
But I am getting only one id, not all the id's. Any idea on how to get all the id's?
I think your Xpath is right. You can verify it with the following test class.
package com.idsk.commons.xsl;
import java.io.IOException;
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.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Test {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("D://NewFile.xml");
// Create XPath
XPathFactory xpathfactory = XPathFactory.newInstance();
XPath xpath = xpathfactory.newXPath();
XPathExpression expr = xpath.compile("*[local-name()='root']/*[local-name()='child']/#id");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
List<String> ids = new ArrayList<>();
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
ids.add(nodes.item(i).getNodeValue()); //store them into List
}
}
}
It will create following output:
2019-05-15-04.52.05.641880A01
2019-05-15-04.52.05.901880A02

Xpath Java unable to get the URL [duplicate]

This question already has answers here:
XPath with namespace in Java
(2 answers)
Closed 4 years ago.
Xpath seems to not work. I've already tried a few things, but nothing seems to work. What am I doing wrong?
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(result)));
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//cm:URL/#value");
String msg = expr.evaluate(doc, XPathConstants.STRING).toString();
logger.debug(msg);
The XML I have looks like this:
<ItemXML xmlns="http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema" xmlns:ns2="http://www.ibm.com/xmlns/db2/cm/api/1.0/schema">
<DOCUMENTS SCA_DATE="#" SCA_NR="#" cm:PID="#" xmlns:cm="http://www.ibm.com/xmlns/db2/cm/api/1.0/schema" xmlns:ns1="http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<cm:properties type="#">
<cm:lastChangeUserid value="#"/>
<cm:lastChangeTime value="#"/>
<cm:createUserid value="#"/>
<cm:createTime value="#"/>
<cm:semanticType value="#"/>
<cm:ACL name="#"/>
<cm:lastOperation name="#" value="#"/>
</cm:properties>
<ns1:CONTRACTS AM="#"/>
<ns1:BASE cm:PID="#" cm:partNumber="#">
<cm:properties type="item" xsi:type="#">
<cm:lastChangeUserid value="#"/>
<cm:lastChangeTime value="#"/>
<cm:createUserid value="#"/>
<cm:createTime value="#"/>
<cm:semanticType value="#"/>
<cm:ACL name="#"/>
<cm:lastOperation name="#" value="#"/>
</cm:properties>
<cm:resourceObject MIMEType="application/pdf" RMName="#" SMSCollName="#" externalObjectName="" originalFileName="#" resourceFlag="#" resourceName="" size="#">
<cm:URL value="https://testurl.com"/>
</cm:resourceObject>
</ns1:BASE>
</DOCUMENTS>
</ItemXML>
I want the value of cm:URL --> https://testurl.com saved as String.
Important: Xpath should find the value regardless of the xml structure.
Without using XPath you can do:
NodeList elementsByTagName = doc.getDocumentElement().getElementsByTagName("cm:URL");
System.out.println("result: " + elementsByTagName.item(0).getAttributes().getNamedItem("value").getNodeValue());
There is issue in following line :-
Document doc = builder.parse(new InputSource(new StringReader(result)));
i tried to print the document, it is giving me output as [#document: null], can you first try to print the document in console and let me know if it is not null.
as suggested by #bangnab use his solution, i tried its working
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.xpath.XPathExpressionException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XpathTester {
public static void main(String[] args) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException {
File inputFile = new File("C:\\Users\\Arvind.Carpenter\\Desktop\\input.txt");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(inputFile);
doc.getDocumentElement().normalize();
NodeList elementsByTagName = doc.getDocumentElement().getElementsByTagName("cm:URL");
//you can iterate over this node list and get all the URL i am printing first one
System.out.println("result: " + elementsByTagName.item(0).getAttributes().getNamedItem("value").getNodeValue());
}
}

Java Xpath multiple elements with same name of a parent node

I have an xml like below.
<name>
<value>123</value>
<value>456</value>
<value>789</value>
</name>
Now using java's Xpath query I tried below method
NodeList list3 = (NodeList) xpath.evaluate("name/value", element,XPathConstants.NODESET);
But it gives me only first value, how can I print all <value> tags ?
Your XPath expression is correct, there is most likely another problem in your code. You really should provide a complete example which demonstrates your problem.
The following code demonstrates how this would look like:
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class XmlTest {
public static void main(String[] args) throws Exception {
String xml = "<name>\n" +
"<value>123</value>\n" +
"<value>456</value>\n" +
"<value>789</value>\n" +
"</name>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
NodeList list = (NodeList) xpath.evaluate("name/value", doc, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); ++i) {
Node node = list.item(i);
System.out.println(node.getNodeName());
}
}
}
Running this results in the following output:
value
value
value

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.

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

Categories

Resources