evaluateXPath runs slow for repeating 1 XML Element in java - java

I have about 1,000,000 XML files and I am using XpathExpression with Java language to walk through the XML tags and get my considered data.
Imagine I have about 5000 tags for name, 5000 tags for family name, 5000 tags for age, and only 1 tag for date in each file. Now I want to repeat date tag to 5000 times too.
Blow code is runnable for XML files with Java programming with less than 20MB size, but I have files with more than 20MB size and it takes so many times to run and in some cases, I got Out of memory error in eclipse( I tried adding vmargs in the run configuration of Eclipse but it takes so much time and still so low.)
I am pretty sure there is a problem with my array for repeting date tag and it is not optimized, I really appreciate if you mind and have a look at my code, in addition I should say that i am newbie to java:
package TEST;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
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.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import java.util.Arrays;
public class Data {
//function started
public static void main(String[] args) throws Exception
{
//Get Files
String doc ="MyFileNew";
String dump="";
int number =200;
for (int i=1; i<=201; i++) {
number ++;
dump = doc+number;
String fileName= "/root/MyFiles/" + dump + ".xml";
Document document = getDocument(fileName);
;
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter pw = null;
//Using Document Builder
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc1 = documentBuilder.parse(fileName);
/*******Get attribute values using xpath******/
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
try {
fw = new FileWriter("/root/Results/" + dump + ".txt");
bw = new BufferedWriter(fw);
pw = new PrintWriter(bw);
//Printing Name tags
pw.println( "Name"+ evaluateXPath(document, "/xml/item/item[#key='Name']/text()") );
//Counting Name tags
XPathExpression expr1 = xpath.compile("count(/xml/item/item[#key='Name']/)");
Number result1 = (Number) expr1.evaluate(doc1, XPathConstants.NUMBER);
int n = result1.intValue();
//Printing FamilyName tags
pw.println( "FamilyName: " + evaluateXPath(document, "/xml/item/item[#key='FamilyName']/text() \n") );
//Printing Age tags
pw.println( "Age: " + evaluateXPath(document, "/xml/item/item[#key='Age']/text() \n") );
//Repeating Date based on counting name tags
String[] strArray = new String[0];
for (int q=0; q<n;q++){
List<String> strArraytmp = evaluateXPath(document,"/xml/item/item[#key='date']/text()");
String[] strings = strArraytmp.stream().toArray(String[]::new);
strArray= Stream.of(strArray, strings ).flatMap(Stream::of).toArray(String[]::new);
}
pw.println("date: " + Arrays.toString(strArray));
System.out.println("this file goes to path:" + "/root/Results/Data/" + dump + ".txt");
pw.flush();
}
catch (IOException e)
{ e.printStackTrace(); } }
}
private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception
{
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
List<String> values = new ArrayList<>();
try
{
// Create XPathExpression object
XPathExpression expr = xpath.compile(xpathExpression);
// Evaluate expression result on XML document
NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
values.add(nodes.item(i).getNodeValue());
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return values;
}
private static Document getDocument(String fileName) throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(fileName);
return doc;
}
}

Related

String to xml elements in java

I'm working on a project in java but I need to create and xml from a list of Strings on this way:
1: "/data/user/firstname/John"
2: "/data/user/middlename/F"
3: "/data/user/lastname/Thomas"
and the expected result should be this one:
<data>
<user>
<firstname>John</firstname>
<middlename>F</middlename>
<lastname>Thomas</lastname>
</user>
<data>
does anyone know if it possible in java? Thank you!
Working example with plain Java, without frameworks:
package test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
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 java.io.File;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
String a = "/data/user/firstname/John";
String b = "/data/user/middlename/F";
String c = "/data/user/lastname/Thomas";
// Create arrays from string and trim first empty space before first '/'
String [] arrayA = Arrays.copyOfRange(a.split("/"), 1, a.split("/").length);
String [] arrayB = Arrays.copyOfRange(b.split("/"), 1, b.split("/").length);
String [] arrayC = Arrays.copyOfRange(c.split("/"), 1, c.split("/").length);
Element parent = null;
for (int i = 0; i < arrayA.length; i++) {
// Append text to child nodes, do it at very end
if (i == arrayA.length - 1) {
Element element1 = (Element) document.getElementsByTagName(arrayA[i - 1]).item(0);
element1.appendChild(document.createTextNode(arrayA[i]));
Element element2 = (Element) document.getElementsByTagName(arrayB[i - 1]).item(0);
element2.appendChild(document.createTextNode(arrayB[i]));
Element element3 = (Element) document.getElementsByTagName(arrayC[i - 1]).item(0);
element3.appendChild(document.createTextNode(arrayC[i]));
break;
}
// if names are same, appending only one of them
if ((arrayA[i].equals(arrayB[i])) && (arrayA[i].equals(arrayC[i]))) {
System.out.println("true");
// create root node
if (i == 0) {
Element element = document.createElement(arrayA[i]);
document.appendChild(element);
parent = element;
System.out.println(document.toString());
} else {
Element element = document.createElement(arrayA[i]);
parent.appendChild(element);
parent = element;
System.out.println(document.toString());
}
// if node names at same levels are different, add all of them
} else {
System.out.println("false");
Element element1 = document.createElement(arrayA[i]);
Element element2 = document.createElement(arrayB[i]);
Element element3 = document.createElement(arrayC[i]);
parent.appendChild(element1);
parent.appendChild(element2);
parent.appendChild(element3);
}
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File("result.xml"));
transformer.transform(domSource, streamResult);
}
}
Output of this program:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><data><user><firstname>John</firstname><middlename>F</middlename><lastname>Thomas</lastname></user></data>
Or, write it to file, then, to last lines need to be:
StreamResult streamResult = new StreamResult(new File("result.xml"));
transformer.transform(domSource, streamResult);

Not able to parse inner elements of XML using DocumentBuilderFactory in Java

I'm having a response as XML. I'm trying to parse the XML object to get inner details. Im using DocumentBuilderFactory for this. The parent object is not null, but when I try to get the deepnode list elements, its returning null. Am I missing anything
Here is my response XML
ResponseXML
<DATAPACKET REQUEST-ID = "1">
<HEADER>
</HEADER>
<BODY>
<CONSUMER_PROFILE2>
<CONSUMER_DETAILS2>
<NAME>David</NAME>
<DATE_OF_BIRTH>1949-01-01T00:00:00+03:00</DATE_OF_BIRTH>
<GENDER>001</GENDER>
</CONSUMER_DETAILS2>
</CONSUMER_PROFILE2></BODY></DATAPACKET>
and Im parsing in the following way
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(responseXML));
// Consumer details.
if(doc.getDocumentElement().getElementsByTagName("CONSUMER_DETAILS2") != null) {
Node consumerDetailsNode = doc.getDocumentElement().getElementsByTagName("CONSUMER_DETAILS2").item(0); -->This is coming as null
dateOfBirth = getNamedItem(consumerDetailsNode, "DATE_OF_BIRTH");
System.out.println("DOB:"+dateOfBirth);
}
getNamedItem
private static String getNamedItem(Node searchResultNode, String param) {
return searchResultNode.getAttributes().getNamedItem(param) != null ? searchResultNode.getAttributes().getNamedItem(param).getNodeValue() : "";
}
Any ideas would be greatly appreciated.
The easiest way to search for individual elements within an XML document is with XPAth. It provides search syntax similar to file system notation.
Here is a solution to the specific problem of you document:
EDIT: solution adopted to support multiple CONSUMER_PROFILE2 elements. You just need to get and parse NodeList instread of one Node
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.*;
public class XpathDemo
{
public static void main(String[] args)
{
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document xmlDoc = builder.parse(new InputSource(new FileReader("C://Temp/xx.xml")));
// Selects all CONSUMER_PROFILE2 elements no matter where they are in the document
String cp2_nodes = "//CONSUMER_PROFILE2";
// Selects first DATE_OF_BIRTH element somewhere under current element
String dob_nodes = "//DATE_OF_BIRTH[1]";
// Selects text child node of current element
String text_node = "/child::text()";
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList dob_list = (NodeList)xPath.compile(cp2_nodes + dob_nodes + text_node)
.evaluate(xmlDoc, XPathConstants.NODESET);
for (int i = 0; i < dob_list.getLength() ; i++) {
Node dob_node = dob_list.item(i);
String dob_text = dob_node.getNodeValue();
System.out.println(dob_text);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Having trouble formatting multiple nodes from a text to XML conversion in Java

I have a Java program which converts text files to XML. I need the following format:
<app:defaults>
<app:schedules>
<app:run>
<app:schedule>schedule frequency value</app:schedule>
</app:run>
</app:schedules>
<app:rununit>
<app:agent>agent hostname value</app:agent>
</app:rununit>
</app:defaults>
The ending "/app:schedules" tag is not appending in the correct place
after the "/app:run" tag. The program is instead generating the following (which is not correct):
<app:defaults>
<app:schedules>
<app:run>
<app:schedule>schedule frequency value</app:schedule>
</app:run>
<app:rununit>
<app:agent>agent hostname value</app:agent>
</app:rununit>
</app:schedules>
</app:defaults>
The method in the java program is as follows: for this example i expilicitly added the text to each node to show what the data should be. - this method takes String args otherwise from the input text file.
public static void main(String[] args) {
String infile = args[0];
String outxml = args[1];
BufferedReader in;
StreamResult out;
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
try {
in = new BufferedReader(new FileReader(infile));
out = new StreamResult(outxml);
icBuilder = icFactory.newDocumentBuilder();
Document doc = icBuilder.newDocument();
Element mainRootElement = doc.createElementNS ("http://dto.cybermation.com/application", "app:appl");
mainRootElement.setAttribute("name", "TESTSHEDULE");
doc.appendChild(mainRootElement);
...
private static Node processTagElements3(Document doc, String "app:defaults") {
Element node1 = doc.createElement("app:schedules");
Element node2 = doc.createElement("app:run");
Element node3 = doc.createElement("app:schedule");
Element node4 = doc.createElement("app:rununit");
Element node5 = doc.createElement("app:agent");
node1.appendChild(node2);
node2.appendChild(node3);
node3.appendChild(doc.createTextNode("schedule frequency value"));
node1.appendChild(node4);
node4.appendChild(node5);
node5.appendChild(doc.createTextNode("agent hostname value"));
return node1;
}
I've tested this using different appenchild parameters between these nodes but ran up against a brick wall with formatiing this output. Any suggestions, advice on the best way to organize the node tag insertions is really appreciated. There could be somthing simple I am missing.
Note: I'm not an expert in for XML parsing in Java.
Just trying to stitch some example codes I got in my machine and see if that solves your problem. So here it is.
Example code:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringReader;
import java.io.StringWriter;\
public class test {
public static void main(String[] args) throws Exception {
String xml = "<app:defaults>\n" +
" <app:schedules>\n" +
" <app:run>\n" +
" <app:schedule>schedule frequency value</app:schedule>\n" +
" </app:run>\n" +
" </app:schedules>\n" +
" <app:rununit>\n" +
" <app:agent>agent hostname value</app:agent>\n" +
" </app:rununit> \n" +
" </app:defaults>";
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new InputSource(new StringReader(xml)));
NodeList errNodes = doc.getElementsByTagName("error");
if (errNodes.getLength() > 0) {
Element err = (Element)errNodes.item(0);
System.out.println(err.getElementsByTagName("errorMessage")
.item(0).getTextContent());
} else {
// success
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
System.out.println(writer.toString());
}
}
Output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<app:defaults>
<app:schedules>
<app:run>
<app:schedule>schedule frequency value</app:schedule>
</app:run>
</app:schedules>
<app:rununit>
<app:agent>agent hostname value</app:agent>
</app:rununit>
</app:defaults>
This code seems to be working as what you will expecting it to be. Give it a try and let me know whether the solution is okay.
I think the idea here is to use pre-baked Java APIs than writing our own parser. Because these APIs are generally more reliable since many others would be using it daily.
Things would be way easier if you had named your nodes with meaningful names (let's say runNode, etc), don't you think?
That being said, this is probably what you want:
Element defaultNode = doc.createElement("app:default");
Element schedulesNode = doc.createElement("app:schedules");
Element runNode = doc.createElement("app:run");
Element scheduleNode = doc.createElement("app:schedule");
Element rununitNode = doc.createElement("app:rununit");
Element agentNode = doc.createElement("app:agent");
defaultNode.appendChild(schedulesNode);
schedulesNode.appendChild(runNode);
runNode.appendChild(scheduleNode);
scheduleNode.appendChild(doc.createTextNode("schedule frequency value"));
defaultNode.appendChild(rununitNode);
rununitNode.appendChild(agentNode);
agentNode.appendChild(doc.createTextNode("agent hostname value"));
Note the defaultNode used.
Thanks all!
I decided to modify the script to accept file input as my arg - this works fine now and is a simpler solution:
public class test2 {
public static void main(String[] args) throws Exception {
File file = new File(args[0]);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try{
DocumentBuilder builder = factory.newDocumentBuilder();
FileInputStream fis = new FileInputStream(file);
InputSource is = new InputSource(fis);
Document doc = builder.parse(is);
NodeList errNodes = doc.getElementsByTagName("error");
if (errNodes.getLength() > 0) {
Element err = (Element)errNodes.item(0);
System.out.println(err.getElementsByTagName("errorMessage").item(0).getTextContent());
} else {
// success
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
System.out.println(writer.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Reading XML as string in Java

Could somebody help me with this. I would like to know how to read this example as string? I know how to read first one but don't know how to read them all
<Tr rn=\"000000000000000\" vr=\"T\" sSpre=\"S\" reg=\"P\" dSpre=\"2000-01-01\" dOdprt=\"2000-01-01\" iban=\"SI00\" eno=\"R\" vir=\"B\" maticnaPps=\"0000000000\"><Imetnik davcna=\"00000000\" matSub=\"0000000000\" drz=\"705\"><PopolnoIme>UNKNOWN</PopolnoIme><KratkoIme>UNKNOWN</KratkoIme><Naslov sifTipNaslova=\"00\" sifObcina=\"000\" sifPosta=\"0000\" sifUlica=\"0000\" sifNaselje=\"000\" stHisna=\"000\" sifHsmid=\"00000000\"><Obcina>UNKNOWN</Obcina><Posta>UNKNOWN</Posta><Ulica>UNKNOWN</Ulica><Naselje>UNKNOWN</Naselje></Naslov></Imetnik></Tr>
Maybe this is what you are looking for? Example here: http://ideone.com/N4jIO
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Main {
public static void main(String... args) throws IOException, SAXException, ParserConfigurationException {
String xml = "<Tr rn=\"000000000000000\" vr=\"T\" sSpre=\"S\" reg=\"P\" dSpre=\"2000-01-01\" dOdprt=\"2000-01-01\" iban=\"SI00\" eno=\"R\" vir=\"B\" maticnaPps=\"0000000000\"><Imetnik davcna=\"00000000\" matSub=\"0000000000\" drz=\"705\"><PopolnoIme>UNKNOWN</PopolnoIme><KratkoIme>UNKNOWN</KratkoIme><Naslov sifTipNaslova=\"00\" sifObcina=\"000\" sifPosta=\"0000\" sifUlica=\"0000\" sifNaselje=\"000\" stHisna=\"000\" sifHsmid=\"00000000\"><Obcina>UNKNOWN</Obcina><Posta>UNKNOWN</Posta><Ulica>UNKNOWN</Ulica><Naselje>UNKNOWN</Naselje></Naslov></Imetnik></Tr>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
print(doc.getDocumentElement(), "");
}
private static void print(Node e, String tab) {
if (e.getNodeType() == Node.TEXT_NODE) {
System.out.println(tab + e.getNodeValue());
return;
}
System.out.print(tab + e.getNodeName());
NamedNodeMap as = e.getAttributes();
if (as != null && as.getLength() > 0) {
System.out.print(" attributes=[");
for (int i = 0; i < as.getLength(); i++)
System.out.print((i == 0 ? "" : ", ") + as.item(i));
System.out.print("]");
}
System.out.println();
if (e.getNodeValue() != null)
System.out.println(tab + " " + e.getNodeValue());
NodeList childs = e.getChildNodes();
for (int i = 0; i < childs.getLength(); i++)
print(childs.item(i), tab + " ");
}
}
If your goal is to load/parse an XML Document from a String object, you'll simply need to use the usual XML document loading code, but to use a StringReader to provide your inputstream. (or a ByteArrayInputStream, or anything really as long as you build up a chain of transformations that lets your access your data as an InputStream).
An example follows here (untested and without exception handling. Sorry, I don't have a test environment at the moment):
final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = f.newDocumentBuilder();
final InputSource is = new InputSource();
is.setCharacterStream(new StringReader(YOURSTRING));
final Document doc = db.parse(is);
doc.getDocumentElement().normalize();
/*
* do whatever you want/need here.
*/
If that's not what you wanted, sorry I am not quite sure what you were asking here.
Using xerces could be more understandable:
public static void loadImetniks(String filePath) {
File xmlFile;
SAXBuilder builder;
Element root, child;
Imetnik imet;//another class that you have to create to help you for parsing
Document doc;
try {
xmlFile = new File(filePath);
builder = new SAXBuilder(); // parameters control validation, etc
doc = builder.build(xmlFile);
root = doc.getRootElement(); // Tr could be the root but I am not sure if you will have more Tr nodes in the same file??
tr.setRn(root.getAttributeValue(Constants.RN));//define the constants string in another file
tr.setVr(root.getAttributeValue(Constants.VR));
tr.setSspre(root.getAttributeValue(Constants.SSPRE));
tr.setReg(root.getAttributeValue(Constants.REG));
tr.setIban(root.getAttributeValue(Constants.IBAN));
.... //repeat for every attribute
....
List children = root.getChildren(); // depends of how many Imetnik you will have
for (Iterator iter = children.iterator(); iter.hasNext();) {
child = (Element) iter.next();
imet = new Imetnik();
imet.loadXML(child); // you have to define the loadXML function in your object Imetnik which should extract the attributes and internal nodes
//imets.add(contest); // just use in the case that you will have to extract more than one Imetnik node
}
} catch (Exception e) {
log.error("Error al hacer el parsing del contests.xml!");
log.error(e.getMessage());
}
}
For instance, your Imetnik class should contain:
public void loadXML(Element root) {
Element child;
//Naslov naslov; // for Naslov because it could be an object itself
davcna = root.getAttributeValue(Constants.DAVCNA); //define the string constant
matSub = root.getAttributeValue(Constants.MATSUB); //define the string constant
drz = Integer.parseInt(root.getAttributeValue(Constants.DRZ)); //define the string constant
List children = root.getChildren(); // your root is Imetnik now
for (Iterator iter = children.iterator(); iter.hasNext();) {
.....
.......
}
}
The best solution to parse XML files in Java is to use a dedicated library such as:
Xerces
Sax

Get the name of all attributes in a XML-File

Hey I have an XML file and I would like to navigate to a given node and grab the name of all Attributes to that node.
For example: (XML File)
<RootName>
<SubNode>
<Attribute1>Value 1</Attribute1>
<Attribute2>Value 2</Attribute2>
</SubNode>
</RootName>
Here is my code so far: (Java Code)
File file = new File("data.xml");
try
{
/* Parse File */
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(file);
/* Find Starting Tag */
NodeList nodes = doc.getElementsByTagName(StartTag);
for (int i = 0; i < nodes.getLength(); i++)
{
Element element = (Element) nodes.item(i);
System.out.println(element);
}
Now I know you can find a specific attribute given the name
String name = element.getAttribute("Attribute1");
But I would like to find all these names dynamically.
Thanks in advance
-Scott
What you are looking for are the Elements. Here is a sample on how to get the Elements in an XML:
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
public class DOMElements{
static public void main(String[] arg){
try {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter XML File name: ");
String xmlFile = bf.readLine();
File file = new File(xmlFile);
if(file.exists()){
// Create a factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Use the factory to create a builder
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlFile);
// Get a list of all elements in the document
NodeList list = doc.getElementsByTagName("*");
System.out.println("XML Elements: ");
for (int i=0; i<list.getLength(); i++) {
// Get element
Element element = (Element)list.item(i);
System.out.println(element.getNodeName());
}
}
else{
System.out.print("File not found!");
}
}
catch (Exception e) {
System.exit(1);
}
}
}
Also see my comment below your question on how to properly design XML and when to use elements, and when to use attributes.
element.getAttributes(); gets you a org.w3c.dom.NamedNodeMap. You can loop through this using the item(int index) method to get org.w3c.dom.Attr nodes, and get the names of those from the getName() method.

Categories