This is my XML file:
<Root>
<Id>1</Id>
<Title>My title</Title>
<More>
<Extension>Ex</Extension>
<Extra>Extra info</Extra>
<Comments>
<Comment date="2018-11-26T06:00:00+02:00">Hey, this is my comment</Comment>
<Comment date="2017-11-26T06:00:00+02:00">Hey, this is my comment</Comment>
<Comment date="2016-11-26T06:00:00+02:00">Hey, this is my comment</Comment>
<Comment date="2011-11-26T06:00:00+02:00">Hey, this is my comment</Comment>
</Comments>
</More>
</Root>
I am only interested in <Comment> data.
My current approach is using JaxB unmarshalling and having classes Root.java, More.java, Comments.java which contains class Comment.java. So it's kinda messy.
I have no problem doing it this way, but I would like to know if there is any method that let's you go straight for the <Comment> data and having only 1 class Comment.java for it?
If you only want to get all the comment tags from the XML file, you may try out following approach,
import java.io.File;
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 ReadComments {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
File xml = new File("D:/data.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
Document doc = docBuilder.parse(xml);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("Comment");
for (int i= 0; i< nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
System.out.printf("Comment : %s | Date : %s\n", node.getTextContent(), element.getAttribute("date"));
}
}
}
}
Output :
Comment : Hey, this is my comment | Date : 2018-11-26T06:00:00+02:00
Comment : Hey, this is my comment | Date : 2017-11-26T06:00:00+02:00
Comment : Hey, this is my comment | Date : 2016-11-26T06:00:00+02:00
Comment : Hey, this is my comment | Date : 2011-11-26T06:00:00+02:00
Note that this is just an example to explain about getting details of specific tags, you will have to modify this code as per for your need.
Related
My problem is in getting the first child of an XML node using the getFirstChild().
My xml is very basic, as follows :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<network name="beep">
<layers number="3">
<layer index="0" lenght="3">
...
</layer>
<layer index="1" lenght="3">
...
</layer>
....
</layers>
</network>
Java-code
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.StringReader;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
try {
DocumentBuilderFactory DBF = DocumentBuilderFactory.newInstance();
DocumentBuilder DB = DBF.newDocumentBuilder();
Document doc = DB.parse(new InputSource( new StringReader(Xml)));
doc.getDocumentElement().normalize();
Element root = doc.getDocumentElement();
NodeList Nodes =root.getElementsByTagName("network");
Node Layers = Nodes.item(0).getFirstChild();
}
catch (Exception ex)
{
}
as you can see there is an element which is a child of "network" and it is a "layer".
I can successfully access to the network, getting the list of nodes, which is basically one node, but as soon as I try to get the first child of the first (and only) node with :
Node Layers = Nodes.item(0).getFirstChild();
I get an exception, and, even funnier, the exception is null.
Where's the problem?
Please try below code(both Files):
1) XML File:
_________
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<network name="beep">
<layers number="3">
<layer index="0" lenght="3">Hare</layer>
<layer index="1" lenght="3">Rama</layer>
<layer index="0" lenght="3">Hare</layer>
<layer index="1" lenght="3">Krishna</layer>
</layers>
</network>
**************************************************************
2) Java File:
__________
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class XMLDemo {
public static void main(String...lsdfs) {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
InputStream inputStream = XMLDemo.class.getClassLoader().getResourceAsStream("dataFilePackage/XmlData.xml");
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(inputStream);
NodeList nodeList = document.getElementsByTagName("network");
System.out.println(nodeList.item(0).getTextContent());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I modified your xml to :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<network name="beep">
<layers number="3">
<layer index="0" lenght="3">Vishwa</layer>
<layer index="1" lenght="3">Ratna</layer>
</layers>
</network>
Java code:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
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 Main {
public static void main(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream inputStream = Main.class
.getClassLoader().getResourceAsStream("resources/nodes.xml");
Document doc = builder.parse(inputStream);
NodeList nodes = doc.getElementsByTagName("network");
System.out.println(nodes.item(0).getTextContent());
} catch (FileNotFoundException | ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
O/P
Vishwa
Ratna
<main-project name="" version="1.0.2">
<data name="data">
<tag>
<link-to object="processor"/>
</tag>
</data>
<output name="output">
<tag>
<link-to object="processor"/>
</tag>
</output>
<processor name ="processor">
<tag>
<link-to object="data"/>
</tag>
</processor>
</main-project>
I wants to get all nodes having having attribute object = processor ,i have tried using
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList linkageNodesEpf = (NodeList) xPath.compile("//link-to[#object = 'processor']").evaluate(Doc, XPathConstants.NODESET);
This query gives empty list but when i replace link-to to link above query works fine and gives correct result,So i think may be dash(-) is creating the problem.
please help me to solve this problem
Well, that code:
import org.w3c.dom.Document;
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 javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class SimpleClass2 {
public static void main(String[] args) throws InterruptedException, XPathExpressionException, ParserConfigurationException, IOException, SAXException {
String str = "<main-project name=\"\" version=\"1.0.2\">\n" +
"<data name=\"data\">\n" +
"<tag>\n" +
"<link-to object=\"processor\"/>\n" +
"</tag>\n" +
"</data>\n" +
"<output name=\"output\">\n" +
"<tag>\n" +
"<link-to object=\"processor\"/>\n" +
"</tag>\n" +
"</output>\n" +
"<processor name =\"processor\">\n" +
"<tag>\n" +
"<link-to object=\"data\"/>\n" +
"</tag>\n" +
"</processor>\n" +
"</main-project>";
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document xmlDoc = builder.parse(new ByteArrayInputStream(str.getBytes()));
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList linkageNodesEpf = (NodeList) xPath.compile("//link-to[#object = 'processor']").evaluate(xmlDoc, XPathConstants.NODESET);
for (int i = 0; i < linkageNodesEpf.getLength(); i++) {
System.out.println(linkageNodesEpf.item(i));
}
}
}
Produces sush results on my machine(oracle jdk8_45):
[link-to: null]
[link-to: null]
Could you try copying it, what results does it produce?
I have XML file like this:
<catalog>
<category>
<books>
<book>
<id>book1</id>
<description>short description</description>
<pages>number of pages</pages>
<author>Anonymous</author>
<name>Book title</name>
</book>
<book>
<id>book2</id>
<description>short description</description>
<pages>number of pages</pages>
<author>Anonymous</author>
<name>Book title</name>
</book>
</books>
</category>
<category>
<books>
<book>
<id>book3</id>
<description>short description</description>
<pages>number of pages</pages>
<author>Anonymous</author>
<name>Book title</name>
</book>
</books>
</category>
</catalog>
And I need an ArrayList with Categories and ArrayList with Books. Here are my Book and Category classes:
public class Book
{
private String id;
private String description;
private String pages;
private String author;
private String name;
}
public class Category {
private ArrayList<Book> books;
private String name;
}
What is the easiest way to do this? Using only android libraries and stuff would be better than using some libraries not for commercial use for my task. I tried some DOM parsers, but it didn't work good.
Actually it can easily be done using dom parser. Here is a stand alone java program to parse your XML file. I am printing values in standard output you can modify it to use in your android application.
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
File fXmlFile = new File("books");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
// iterate through <category> tags
NodeList categoryList = doc.getElementsByTagName("category");
for (int categoryNo=0;categoryNo<categoryList.getLength();categoryNo++) {
Element categoryNode = (Element)categoryList.item(categoryNo);
System.out.println("Category No " +categoryNo);
//iterate through <books> tags
NodeList booksList = categoryNode.getElementsByTagName("books");
for (int booksNo=0;booksNo<booksList.getLength();booksNo++) {
Element books = (Element)booksList.item(0);
// iterate through <book> tags
NodeList bookList = books.getElementsByTagName("book");
for(int bookNo=0;bookNo<bookList.getLength();bookNo++) {
Element bookElement = (Element)bookList.item(bookNo);
System.out.println(bookElement.getElementsByTagName("id").item(0).getTextContent());
System.out.println(bookElement.getElementsByTagName("description").item(0).getTextContent());
System.out.println(bookElement.getElementsByTagName("pages").item(0).getTextContent());
System.out.println(bookElement.getElementsByTagName("author").item(0).getTextContent());
System.out.println(bookElement.getElementsByTagName("name").item(0).getTextContent());
}
}
}
}
}
Have a look at android xml pull parser, this page has examples too
(it is a SAX parser)
This question already has answers here:
Remove 'standalone="yes"' from generated XML
(13 answers)
Closed 9 years ago.
I wrote code for tests - it creates simple XML document. My problem is that created document contains unneeded data in first node . Is any way to delete or modify this node <?xml version="1.0" encoding="UTF-8" standalone="no"?> ?
import java.io.ByteArrayOutputStream;
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;
public class MyTestClass {
public static void main(String argv[]) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("company");
doc.appendChild(rootElement);
// staff elements
Element staff = doc.createElement("Staff");
rootElement.appendChild(staff);
// firstname elements
Element firstname = doc.createElement("firstname");
firstname.appendChild(doc.createTextNode("yong"));
staff.appendChild(firstname);
// lastname elements
Element lastname = doc.createElement("lastname");
lastname.appendChild(doc.createTextNode("mook kim"));
staff.appendChild(lastname);
// nickname elements
Element nickname = doc.createElement("nickname");
nickname.appendChild(doc.createTextNode("mkyong"));
staff.appendChild(nickname);
// salary elements
Element salary = doc.createElement("salary");
salary.appendChild(doc.createTextNode("100000"));
staff.appendChild(salary);
Transformer t = TransformerFactory.newInstance().newTransformer();
ByteArrayOutputStream s = new ByteArrayOutputStream();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
t.transform(new DOMSource(doc),new StreamResult(s));
System.out.println(new String(s.toByteArray()));
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}
It returns:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<company>
<Staff>
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</Staff>
</company>
Is any way to delete or modify this node <?xml version="1.0" encoding="UTF-8" standalone="no"?> ?
You can add the following to your Transformer
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
see here for details
I have this sample xml.
Each row has an id field, it has values as bits.
And I want to find in this file with bitwise-and operator but I don't know if this is possible.
I read about the operator '&' in javascript or comand BITAND in Oracle but nothing in xml o xpath.
This is the example code in java and xpath:
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Util implements java.io.Serializable {
static public String filter_xpath_bitand (int var_tipo)
NodeList nodeList = null;
Element element = null;
try {
XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(fileXML));
nodeList = (NodeList)xpath.evaluate("/test/row[(id & \""+ var_tipo +"\") > 1]", document.getDocumentElement(), XPathConstants.NODESET);
} catch (Exception e) {
System.out.println("*** filterXML --> exception: " + e.toString());
}
}
}
From looking at the XPATH reference there is no such thing as bitwise operations.
You could work around that though by making use of existing operations (mod etc).
See here for a related question.
EDIT:
Sample xml:
<?xml version="1.0" encoding="UTF-8"?>
<test>
<row>
<id>32</id>
<titulo>yellow</titulo>
</row>
<row>
<id>16</id>
<titulo>green</titulo>
</row>
<row>
<id>8</id>
<titulo>red</titulo>
</row>
<row>
<id>1</id>
<titulo>blue</titulo>
</row>
<row>
<id>2</id>
<titulo>white</titulo>
</row>
<row>
<id>4</id>
<titulo>black</titulo>
</row>
</test>
Java code:
import java.io.File;
import java.util.HashSet;
import java.util.Set;
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;
public class BitWiseXPathTest {
public static void main(String[] args) {
Set<String> selectedColors = new HashSet<String>();
int var_tipo = 33;
try {
XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
String fileXML = "bitwise.xml";
Document document = builder.parse(new File(fileXML));
String evalStr = "/test/row/id";
NodeList nodeList = (NodeList)xpath.evaluate(evalStr, document.getDocumentElement(), XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node aNode = nodeList.item(i);
if( (Integer.parseInt(aNode.getTextContent()) & var_tipo) > 0) {
//System.out.println("color: "+aNode.getNextSibling().getNextSibling().getTextContent());
selectedColors.add(aNode.getNextSibling().getNextSibling().getTextContent());
}
}
} catch (Exception e) {
System.out.println("*** filterXML --> exception: " + e.toString());
}
System.out.println(selectedColors);
}
}
Again, XPATH doesn't seem to have a bitwise operation. You could move the operation outside of XPATH and do it in Java as a workaround.