Parse xml dom to an object - java

How can I fill an array with such object?
class Sam{
String id;
String type;
String data;
}
from xml structure:
<Table name="Sam">
<Row id="374058">
<Col name="ID.1">374058</Col>
<Col name="TYPE.1">mob</Col>
</Row>
<Row id="374059">
<Col name="ID.1">374059</Col>
<Col name="TYPE.1">ff</Col>
</Row>
</Table>
Found such "Table" but what i shoud do next to collect data from "Row"?
List<Sam> samList = new new ArrayList<>();
NodeList nameNodeList = xml.getDocumentElement().getElementsByTagName("Table");
if (nameNodeList != null) {
for (int i = 0; i < nameNodeList.getLength(); i++) {
Node node = nameNodeList.item(i);
if (node.getAttributes().getNamedItem("name").getNodeValue().equals("Sam") &&
node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
//what should i do next, how can i fined ID,TYPE,DATA?
}
}
}

Try this one. I try to code the problem and get the following output. This code parses your XML and constructs the Sam object.
Code:
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.NodeList;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
public class XmlParse {
public static void main(String[] args) {
XmlParse xmlParse = new XmlParse();
xmlParse.xmlToObj();
}
public void xmlToObj() {
try {
File inputFile = new File("sam.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputFile);
doc.getDocumentElement().normalize();
System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
NodeList nodeList = doc.getElementsByTagName("Row");
Node node = null;
List<Sam> samList = new ArrayList<>();
if(nodeList != null && nodeList.getLength() > 0) {
for(int i=0; i < nodeList.getLength(); i++) {
node = nodeList.item(i);
NodeList innerNodeList = doc.getElementsByTagName("Col");
Node innerNodeID = innerNodeList.item(0);
Node innerNodeType = innerNodeList.item(1);
String id = innerNodeID.getTextContent();
String type = innerNodeType.getTextContent();
Sam sam = new Sam(id, type, null);
System.out.println(sam.toString());
samList.add(sam);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
class Sam {
String id;
String type;
String data;
public Sam(String id, String type, String data) {
this.id = id;
this.type = type;
this.data = data;
}
#Override
public String toString() {
return "Sam [id=" + id + ", type=" + type + ", data=" + data + "]";
}
}
Output:
Root element: Table
Sam [id=374058, type=mob, data=null]
Sam [id=374058, type=mob, data=null]
input : sam.xml
<Table name="Sam">
<Row id="374058">
<Col name="ID">374058</Col>
<Col name="TYPE">mob</Col>
</Row>
<Row id="374059">
<Col name="ID">374059</Col>
<Col name="TYPE">ff</Col>
</Row>
</Table>

you can use JAXB Unmarshalling
You can also see some examples in Examples JAXB Unmarshalling

Related

Java XML - Can you jump down directly to a deep reference or do you have to iterate through? [duplicate]

This is an academic assignment and we are given an extremely large XML file with hundreds of entries like these. For each item we are supposed to list the Manager's ID, the Person's ID of the last person to add an item to the list, and the current number of items. I have read and reread the Oracle DOM API and various Node APIs. We are using JAVA and I cannot for the life of me figure out how to search various 'fields' of each item_list node. Below is an example of the data we are given.
<item_list id="item_list01">
<numitems_intial>5</numitems_initial>
<item>
<date_added>1/1/2014</date_added>
<added_by person="person01" />
</item>
<item>
<date_added>1/6/2014</date_added>
<added_by person="person05" />
</item>
<numitems_current>7</numitems_current>
<manager person="person48" />
</item_list>
<item_list id="item_list02">
<numitems_intial>5</numitems_initial>
<item>
<date_added>1/15/2014</date_added>
<added_by person="person05" />
</item>
<item>
<date_added>1/1/2014</date_added>
<added_by person="person09" />
</item>
<item>
<date_added>1/9/2014</date_added>
<added_by person="person45" />
</item>
<numitems_current>7</numitems_current>
<manager person="person38" />
</item_list>
I've tried doing something similar to:
NodeList nodes = queryDoc.getElementsByTagName("item_list");
for(int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if(node != null) {
System.out.println(node.manager);
}
}
And messing around with this code for a while, but I would like to know how to retrieve data from various fields in each node.
If you are trying to read person attribute of manager tag, you can do it as shown below -
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Test{
public static void main (String[] args)
{
Test test = new Test();
test.readXML();
}
private void readXML()
{
Document doc = null;
try
{
doc = parseXML("/home/abc/Test.xml");
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
catch (SAXException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
if(doc != null)
{
NodeList nList = doc.getElementsByTagName("item_list");
for (int i = 0; i < nList.getLength(); i++)
{
Node nNode = nList.item(i);
Element eElement = (Element) nNode;
Element cElement = (Element) eElement.getElementsByTagName("manager").item(0);
System.out.println("Manager ID : " + cElement.getAttribute("person"));
}
}
}
private Document parseXML(String filePath) throws ParserConfigurationException, SAXException, IOException
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(filePath);
doc.getDocumentElement().normalize();
return doc;
}
}
Or, using xml you might need to edit the initial content. I suggest the following approach
import java.io.IOException;
import java.io.StringWriter;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
public class ReadXML {
public static void main(String[] args) {
try {
Document doc = getDocument("/home/abc/Test.xml");
System.out.println(getString(getNodeByName(doc,"item_list01")));
} catch (TransformerException | ParserConfigurationException | IOException | SAXException e) {
// Log e.printStackTrace();
}
}
private static Document getDocument(String filePath) throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
return docBuilder.parse(filePath);
}
private static String getString(Node node) throws TransformerException {
StringWriter sw = new StringWriter();
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(node), new StreamResult(sw));
return sw.toString();
}
public static Node getNodeByName(Document doc, String nodeName) {
Node node = null;
for (int i = 0; i < doc.getDocumentElement().getChildNodes().getLength(); i++) {
if (!getTagName(doc, i).equals("#text")) {
for (int j = 0; j < getNodeName(doc, i).getChildNodes().getLength(); j++) {
if (getNodeName(doc, i, j).equalsIgnoreCase("item_list") && getNodeAttributes(doc,i,j).equalsIgnoreCase(nodeName)) {
node = getNodeName(doc, i);
}
}
}
}
return node;
}
private static String getTagName(Document doc, int i) {
return getNodeName(doc, i).getNodeName();
}
private static Node getNodeName(Document doc, int i) {
return (doc.getDocumentElement().getChildNodes().item(i));
}
private static String getNodeName(Document doc, int i, int j) {
return getNodeName(doc, i).getChildNodes().item(j).getNodeName();
}
private static String getNodeAttributes(Document doc, int i, int j) {
if(getNodeName(doc, i).getChildNodes().item(j).hasAttributes()){
return getNodeName(doc, i).getChildNodes().item(j).getAttributes().item(0).getNodeValue();
}
return "";
}
}

How to read an online XML file for currency rates in java

I'm building a simple currency converter which needs to sue online rates. I found the following API from the European Central Bank to use:
http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
My problem is im struggling to implement it. Here is what i have so far after using a bunch of different sources to try and get this code together.
try{
URL url = new URL("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList1 = doc.getElementsByTagName("Cube");
for(int i = 0; i < nodeList1.getLength(); i++){
Node node = nodeList1.item(i);
}
}
catch(Exception e){
}
So what i thought is that this code would take down all the nodes which tart with "Cube", and contain the rates.
Anyone have an easier wya to pull down the rates from the API into an array in the order they appear on the XML as that's all I'm trying to do
Thanks
XPath is one way to answer this, since you just want to extract information from the XML and not change the XML. The structure of the XML suggests that you're looking for nodes that are Cube nodes, that are child of Cube which is also a child of Cube -- Cube nested three times, so extract nodes with an XPath compiled using this String: "//Cube/Cube/Cube". This looks for nodes that have Cube nested 3 times located anywhere (the //) in the Document:
XPathExpression expr = xpath.compile("//Cube/Cube/Cube");
Then check the nodes for a "currency" attribute. If they have this, then they also have a "rate" attribute, and then extract this information.
NamedNodeMap attribs = node.getAttributes();
if (attribs.getLength() > 0) {
Node currencyAttrib = attribs.getNamedItem(CURRENCY);
if (currencyAttrib != null) {
String currencyTxt = currencyAttrib.getNodeValue();
String rateTxt = attribs.getNamedItem(RATE).getNodeValue();
// ...
}
}
Where CURRENCY = "currency" and RATE = "rate"
For example:
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
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 TestXPath {
private static final String CURRENCY = "currency";
private static final String CUBE_NODE = "//Cube/Cube/Cube";
private static final String RATE = "rate";
public static void main(String[] args) {
List<CurrencyRate> currRateList = new ArrayList<>();
DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = builderFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
Document document = null;
String spec = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
try {
URL url = new URL(spec);
InputStream is = url.openStream();
document = builder.parse(is);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
String xPathString = CUBE_NODE;
XPathExpression expr = xpath.compile(xPathString);
NodeList nl = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
NamedNodeMap attribs = node.getAttributes();
if (attribs.getLength() > 0) {
Node currencyAttrib = attribs.getNamedItem(CURRENCY);
if (currencyAttrib != null) {
String currencyTxt = currencyAttrib.getNodeValue();
String rateTxt = attribs.getNamedItem(RATE).getNodeValue();
currRateList.add(new CurrencyRate(currencyTxt, rateTxt));
}
}
}
} catch (SAXException | IOException | XPathExpressionException e) {
e.printStackTrace();
}
for (CurrencyRate currencyRate : currRateList) {
System.out.println(currencyRate);
}
}
}
public class CurrencyRate {
private String currency;
private String rate; // ?double
public CurrencyRate(String currency, String rate) {
super();
this.currency = currency;
this.rate = rate;
}
public String getCurrency() {
return currency;
}
public String getRate() {
return rate;
}
#Override
public String toString() {
return "CurrencyRate [currency=" + currency + ", rate=" + rate + "]";
}
// equals, hashCode,....
}

Creating a XML parser for Java

I'm making a Java application that displays X3D models and I'm creating an XML parser for it. The Java code that I have for it is
package domparserexample.java;
import java.io.IOException;
import java.util.Iterator;
import javax.lang.model.element.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomParserExampleJava {
private void parseXmlFile() throws IOException, ParserConfigurationException{
//get the factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
//parse using builder to get DOM representation of the XML file
Document dom = db.parse("employees.xml");
}catch(SAXException se) {
se.printStackTrace();
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
private void parseDocument(){
//get the root element
Element docEle = dom.getDocumentElement();
//get a nodelist of elements
NodeList nl = docEle.getElementsByTagName("Employee");
if(nl != null && nl.getLength() > 0) {
for(int i = 0 ; i < nl.getLength();i++) {
//get the employee element
Element el = (Element)nl.item(i);
//get the Employee object
Employee e = getEmployee(el);
//add it to list
myEmpls.add(e);
}
}
}
/**
* I take an employee element and read the values in, create
* an Employee object and return it
*/
private Employee getEmployee(Element empEl) {
//for each <employee> element get text or int values of
//name ,id, age and name
String name = getTextValue(empEl,"Name");
int id = getIntValue(empEl,"Id");
int age = getIntValue(empEl,"Age");
String type = empEl.getAttribute("type");
//Create a new Employee with the value read from the xml nodes
Employee e = new Employee(name,id,age,type);
return e;
}
private String getTextValue(Element ele, String tagName) {
String textVal = null;
NodeList nl = ele.getElementsByTagName(tagName);
if(nl != null && nl.getLength() > 0) {
Element el = (Element)nl.item(0);
textVal = el.getFirstChild().getNodeValue();
}
return textVal;
}
private int getIntValue(Element ele, String tagName) {
//in production application you would catch the exception
return Integer.parseInt(getTextValue(ele,tagName));
}
private void printData(){
System.out.println("No of Employees '" + myEmpls.size() + "'.");
Iterator it = myEmpls.iterator();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
}
}
And the XML code is:
<?xml version="1.0" encoding="UTF-8"?>
<Personnel>
<Employee type="permanent">
<Name>Seagull</Name>
<Id>3674</Id>
<Age>34</Age>
</Employee>
<Employee type="contract">
<Name>Robin</Name>
<Id>3675</Id>
<Age>25</Age>
</Employee>
<Employee type="permanent">
<Name>Crow</Name>
<Id>3676</Id>
<Age>28</Age>
</Employee>
</Personnel>
However, I'm getting some errors on lines 49, 76, 93, and 96 in the DomParserExample.java file and I don't know why it's happening. All the errors say that they cannot find symbol and symbol: method getElemantsByTagName(String), symbol: method getAttribute(String), symbol: method getElementByTagName(String), and symbol: method getFirstChild().
For me it is working with the following code. I made some changes to your code.
DomParserExampleJava.java
package domparserexample.java;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomParserExampleJava {
private List<Employee> myEmpls = new ArrayList<Employee>();
public static void main(String[] args) throws IOException, ParserConfigurationException {
DomParserExampleJava domParser = new DomParserExampleJava();
domParser.parseXmlFile();
}
private void parseXmlFile() throws IOException, ParserConfigurationException {
// get the factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// parse using builder to get DOM representation of the XML file
Document dom = db.parse("employees.xml");
parseDocument(dom);
printData();
} catch (SAXException se) {
se.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
private void parseDocument(Document dom) {
// get the root element
Element docEle = dom.getDocumentElement();
// get a nodelist of elements
NodeList nl = docEle.getElementsByTagName("Employee");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
// get the employee element
Element el = (Element) nl.item(i);
// get the Employee object
Employee e = getEmployee(el);
// add it to list
myEmpls.add(e);
}
}
}
/**
* I take an employee element and read the values in, create an Employee object and return it
*/
private Employee getEmployee(Element empEl) {
// for each <employee> element get text or int values of
// name ,id, age and name
String name = getTextValue(empEl, "Name");
int id = getIntValue(empEl, "Id");
int age = getIntValue(empEl, "Age");
String type = empEl.getAttribute("type");
// Create a new Employee with the value read from the xml nodes
Employee e = new Employee(name, id, age, type);
return e;
}
private String getTextValue(Element ele, String tagName) {
String textVal = null;
NodeList nl = ele.getElementsByTagName(tagName);
if (nl != null && nl.getLength() > 0) {
Element el = (Element) nl.item(0);
textVal = el.getFirstChild().getNodeValue();
}
return textVal;
}
private int getIntValue(Element ele, String tagName) {
// in production application you would catch the exception
return Integer.parseInt(getTextValue(ele, tagName));
}
private void printData() {
System.out.println("No of Employees '" + myEmpls.size() + "'.");
Iterator<Employee> it = myEmpls.iterator();
while (it.hasNext()) {
System.out.println(it.next().toString());
}
}
}
Employee.java
package domparserexample.java;
public class Employee {
private String name;
private int id;
private int age;
private String type;
public Employee(String name, int id, int age, String type) {
this.name = name;
this.id = id;
this.age = age;
this.type = type;
}
public String toString() {
return id + ": " + name + ", age: " + age + ", type: " + type;
}
}
employees.xml
In your example <?xml version="1.0" encoding="UTF-8"?> appears a second time in the middle of the XML document. This lead to an error.
<?xml version="1.0" encoding="UTF-8"?>
<Personnel>
<Employee type="permanent">
<Name>Seagull</Name>
<Id>3674</Id>
<Age>34</Age>
</Employee>
<Employee type="contract">
<Name>Robin</Name>
<Id>3675</Id>
<Age>25</Age>
</Employee>
<Employee type="permanent">
<Name>Crow</Name>
<Id>3676</Id>
<Age>28</Age>
</Employee>
</Personnel>
If I execute the Java file it returns:
No of Employees '3'.
3674: Seagull, age: 34, type: permanent
3675: Robin, age: 25, type: contract
3676: Crow, age: 28, type: permanent
You are using the wrong ELementclass:
import javax.lang.model.element.Element;
is wrong, use:
import org.w3c.dom.Element;
That should work.

XML parsing with Child not value parsing

XML parsing with Child not value parsing
import java.io.File;
import java.io.FileInputStream;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList;
public class XPathEvaluator {
/*
* ServiceGroup serviceGroup = new ServiceGroup(); List<Service>
* requiredServices = new ArrayList<Service>(); List<Service>
* recommandedServices = new ArrayList<Service>(); Service service = new
* Service();
*/
public void evaluateDocument(File xmlDocument) {
try {
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
String requiredServicesExpression = "/Envelope/Header";
InputSource requiredServicesInputSource = new InputSource(
new FileInputStream(xmlDocument));
DTMNodeList requiredServicesNodes = (DTMNodeList) xPath.evaluate(
requiredServicesExpression, requiredServicesInputSource,
XPathConstants.NODESET);
System.out.println(requiredServicesNodes.getLength());
NodeList requiredNodeList = (NodeList) requiredServicesNodes;
for (int i = 0; i < requiredNodeList.getLength(); i++) {
Node node = requiredNodeList.item(i);
System.out.println(node.getChildNodes());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] argv) {
XPathEvaluator evaluator = new XPathEvaluator();
File xmlDocument = new File("d://eva.xml");
evaluator.evaluateDocument(xmlDocument);
}
}
my xml is following in this i am try to parse header information
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<Header>
<User id="MAKRISH"/>
<Request-Id id="1"/>
<Type name="Response"/>
<Application-Source name="vss" version="1.0"/>
<Application-Destination name="test" />
<Outgo-Timestamp date="2012-08-24" time="14:50:00"/>
<DealerCode>08301</DealerCode>
<Market>00000</Market>
</Header>
</Envelope>
i am not able to get Header child how can i get them it is giving me null on getchildNodes method. i have check for many solution but get any thing.
The following parsing is done with DOM as per tagging , i hope this should help you to solve
{
try{
File file = new File("xmlfile");
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(file);
Element root = document.getDocumentElement();
root.normalize();
printNode(root, 0);
} catch (Exception e) {
}
}
public static void printNode(Node node, int depth) {
if (node.getNodeType() == Node.TEXT_NODE) {
System.out.printf("%s%n", node.getNodeValue());
} else {
NamedNodeMap attributes = node.getAttributes();
if ((attributes == null) || (attributes.getLength() == 0)) {
System.out.printf("%s%n", node.getNodeName());
} else {
System.out.printf("%s ", node.getNodeName());
printAttributes(attributes);
}
}
NodeList children = node.getChildNodes();
for(int i=0; i<children.getLength(); i++) {
Node childNode = children.item(i);
printNode(childNode, depth+1);
}
}
private static void printAttributes(NamedNodeMap attributes) {
for(int i=0; i<attributes.getLength(); i++)
{
Node attribute = attributes.item(i);
System.out.printf(" %s=\"%s\"", attribute.getNodeName(),
attribute.getNodeValue());
}
}
}
The accepted answer to this related question has a good example of parsing xml using xpath.
I've debugged into your code, and the getChildNodes call is in fact not returning null, but it has got a confusing toString().

How to get attribute in XML

Thanks for previous replies.
I am parsing XML file using java(SAXParser), i am not sure how to parse the attribute value(meta data) using attribute value. I given two main categoy
<category name="XYZ" /> <category name="ABC"/>
'
<subcategory name="" loc="C://program files" link="www.sample.com" parentnode="XYZ"/>
<subcategory name="" loc="C://program files" link="http://" parentnode="ABC"/>`
In sub category i have linked the main category with parentnode attribute. my question is i want to get all the attribute which is only contains particular parent attribute. (Ex)i want all attribute which is only resides in parent attribute "ABC". is this possible to get a value.
Does the code below is solution for your problem?
XML
<?xml version="1.0"?>
<categories>
<category name="ABC">
<subcategory name="123"
loc="C://program files"
link="www.sample.com"
parentnode="ABC"/>
<subcategory name="456"
loc="C://program files"
link="http://"
parentnode="ABC"/>
</category>
<category name="XYZ">
<subcategory name="123"
loc="C://program files"
link="www.sample.com"
parentnode="XYZ"/>
<subcategory name="456"
loc="C://program files"
link="http://abc.com"
parentnode="XYZ"/>
</category>
</categories>
JAVA
package com.stackoverflow;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Question6855476 {
private static final String CFG_XML_PATH = "D:\\sample\\path\\question6855476.xml";
private static final String searchArg = "ABC";
public static void main(String[] args) {
List locList = getLocsByCategoryName(searchArg);
List linkList = getLinksByCategoryName(searchArg);
printCollection(locList,"LOC");
printCollection(linkList,"LINKS");
}
private static void printCollection(List locList, String string) {
System.out.println();
System.out.println("### Collection: "+string+"\n");
if(locList.isEmpty()) {
System.out.println("\tNo items. Collection is empty.");
} else {
for(Object obj: locList) {
System.out.println("\t"+obj);
}
}
}
private static List getLocsByCategoryName(String catName) {
if(null==catName||catName.length()<=0) {
System.out.println("ERROR: catName is null/blank");
return Collections.EMPTY_LIST;
} else {
return getSubcatAttrValuesByAttrName("loc", catName);
}
}
private static List getLinksByCategoryName(String catName) {
if(null==catName||catName.length()<=0) {
System.out.println("ERROR: catName is null/blank");
return Collections.EMPTY_LIST;
} else {
return getSubcatAttrValuesByAttrName("link", catName);
}
}
private static List<Object> getSubcatAttrValuesByAttrName(String attrName, String catName) {
List<Object> list = new ArrayList<Object>();
if(null==attrName||attrName.length()<=0) {
System.out.println("ERROR: attrName is null/blank");
} else {
try {
File file = new File(CFG_XML_PATH);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
NodeList catLst = doc.getElementsByTagName("category");
for (int i = 0; i < catLst.getLength(); i++) {
Node cat = catLst.item(i);
NamedNodeMap catAttrMap = cat.getAttributes();
Node catAttr = catAttrMap.getNamedItem("name");
if(catName.equals(catAttr.getNodeValue())){ // CLUE!!!
NodeList subcatLst = cat.getChildNodes();
for (int j = 0; j < subcatLst.getLength(); j++) {
Node subcat = subcatLst.item(j);
NamedNodeMap subcatAttrMap = subcat.getAttributes();
if(subcatAttrMap!=null) {
Node subcatAttr = subcatAttrMap.getNamedItem(attrName);
list.add(subcatAttr.getNodeValue());
}
}
}
}
} catch (Exception e) { // FIXME
e.printStackTrace();
}
}
return list;
}
}
I've based on this article
I am assuming you mean you want to get all the attributes of subcategory elements with parentnode attribute value equals to "ABC"? So you want to get the attributes (name="" loc="C://program files" link="http://" parentnode="ABC") in the example you gave?
The basic parsing code should look like this:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
MySAXHandler handler = new MySAXHandler();
handler.setDesireParentNodeAttributeValue("ABC");
parser.parse(xmlInputStream, handler);
/*
*this list contains all the attributes of the subcategory element that has
* parentnode attribute equals to "ABC"
*/
List<Attributes> whatIWant = handler.getDesireAttributes();
//do whatever you wnat with "whatIWant"
....
public class MySAXHandler extends DefaultHandler2
{
private String desirePrentNodeAttributeValue;
private List<Attributes> desireAttributes = new ArrayList<Attributes>();
public void setDesireParentNodeAttributeValue(String val)
{
this.desirePrentNodeAttributeValue = val;
}
public List<Attributes> getDesireAttributes()
{
return desireAttributes;
}
public void startElement(String uri,
String localName,
String qName,
Attributes attributes)
throws SAXException
{
if ("subcategory".equals(localName)
&& attributes
.getValue("parentnode")
.equals(this.desirePrentNodeAttributeValue))
{
desireAttributes.add(attributes);
}
}
}
Once you've parsed you XML you could wander through the data to find what you need, but a better approach may be to use XPath to query the XML.
There some tutorial material here

Categories