I'm trying to parse this XML in Java:
<entities>
<entity name="product_section" id="1">
<product_type>3</product_type>
<section_type>1</section_type>
<name>Empresa</name>
<description>d</description>
<position>1</position>
<align>left</align>
<files section_id="1">
<ico id="ico_1" type="normal" src="sections/1/icons/ico.png"></ico>
<ico id="ico_2" type="hover" src="sections/1/icons/ico.png"></ico>
<ico id="ico_3" type="active" src="sections/1/icons/ico.png"></ico>
<img id="img_1" type="normal" src="sections/1/img/pestanya.png"></img>
<img id="img_2" type="hover" src="sections/1/img/pestanya-hover.png"></img>
<img id="img_3" type="active" src="sections/1/img/pestanya-active.png"></img>
<background id="background_1" type="background" position="1" src="sections/1/background/bg1.png"></background>
<background id="background_2" type="background" position="2" src="sections/1/background/bg2.png"></background>
<background id="background_3" type="background" position="3" src="sections/1/background/bg3.png"></background>
</files>
</entity>
But I just achieved to loop through Entities, getting all Entity and each <product_type>, <section_type>, etc.
But I want to loop through files too.
This is my implementation so far:
try {
File contingut = new File("xmlfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(contingut);
doc.getDocumentElement().normalize();
System.out.println("root of xml file " + doc.getDocumentElement().getNodeName());
//loop a cada entity
NodeList nodes = doc.getElementsByTagName("entity");
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
Element element = (Element) node;
System.out.println("product_type: " + getValue("product_type", element));
System.out.println("section_type: " + getValue("section_type", element));
System.out.println("name: " + getValue("name", element));
System.out.println("description: " + getValue("description", element));
System.out.println("position: " + getValue("position", element));
System.out.println("align: " + getValue("align", element));
}
} catch (Exception e){
e.printStackTrace();
}
getValue function is:
private static String getValue(String tag, Element element) {
NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
Node node = (Node) nodes.item(0);
return node.getNodeValue();
}
I've done lot of google search, and all I find are "simple" examples, with a parent, and a child, but not child's child.
Any help would be appreciated.
At first one suggestion:
check element type after this Element element = (Element) node;
use this code or something like this :
if (element.getNodeType() == Element.ELEMENT_NODE) { // do smth}
and answer to your question:
You can simply rewrite you code. after you create element you can get all it's child elements by using element.getChildNodes();
it gives you all child tags. After that you write simple for loop where you get each node element from node list like this :
NodeList nodes = element.getChildNodes();
for(int i =0; i < nodes.getLength(); i++){
Element child = (Element) nodes.item(i);
if(child.getNodeType() == Element.ELEMENT_NODE){
String tagName = child.getTagName();
if(!tagName.equals("files")){
System.out.println(tagName + " : " + child.getTextContent());
}else{
NodeList filesChilds = child.getChildNodes();
for(int j = 0; j < filesChilds.getLength(); j++){
//and like above
}
}
}
}
Related
I'm having a slight problem with XML parsing.
I'm creating a function where the parameter is a certain "element" from the XML file.
When found, I want to return the value of the root attribute.
Here's my code:
FileInputStream file = new FileInputStream(new File("C:\\Users\\Grizzly\\Java\\Projet_16_17-20161214\\bdd.xml"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
if(nNode.toString().equalsIgnoreCase(element))
{
Element eElement = (Element) nNode;
System.out.println("Taxe= "+ eElement.getAttribute("taxe"));
}
}
}
Any idea on how to do this?
Here's my XML file:
<?xml version="1.0"?>
-<types>
-<type id="Nourriture" taxe="0.1">
<element>pomme</element>
<element>fraise</element>
<element>fromage</element>
<element>viande rouge </element>
</type>
-<type id="Matiere Premiere" taxe="0.2">
<element>fer</element>
<element>polypropylene</element>
</type>
-<type id="Element Solide" taxe="0.3">
<element>voiture</element>
<element>planche surf</element>
<element>pistolet</element>
</type>
</types>
In my code, I tried to get the elements of a certain node from the nodelist and then compare it to the the string "element" which is the input of the user, and if they match it will check the attribute value of taxe linked to it.
Thanks in advance.
EDIT: I'm getting closer to what I need:
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
NodeList nChildren = nNode.getChildNodes();
Element eElement = (Element) nNode;
for(int i = 0; i < nChildren.getLength(); i++)
{
String onElement = eElement.getElementsByTagName("element").item(i).getTextContent();
if(onElement.equalsIgnoreCase(element))
{
System.out.println("id : " + eElement.getAttribute("id"));
System.out.println("taxe : " + eElement.getAttribute("taxe"));
break;
}
}
}
But it's only reading the first element... and item(i) isn't working.
Any idea?
If I understand you correctly, you are trying to fetch specific attributes (id and taxe) of all the document nodes having at least one child element with specific name (element).
Although the problem can be solved by iterating the DOM and keeping the states, I would rather delegate this task to XPath. A code with XPath will look cleaner and be more maintainable. For example, in order to fetch all elements having attributes id and taxe and a child element element you can use an XPath expression like //*[#id and #taxe element]. The matching nodes are fetched in a single line. You can simply iterate the nodes and collect the attributes as shown in the following example.
Example
public static void main(String args[]) {
String element = args.length > 0 ? args[0] : "element";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
FileInputStream file = new FileInputStream(new File("/some/file.xml"));
Document doc = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//*[#id and #taxe and " + element + "]";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
NamedNodeMap attributes = node.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
Node aNode = attributes.item(j);
System.out.printf(
"%s: %s\n",
aNode.getNodeName(),
aNode.getNodeValue()
);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
Sample Output
id: Nourriture
taxe: 0.1
id: Matiere Premiere
taxe: 0.2
id: Element Solide
taxe: 0.3
Note, the sample above prints all attributes of the parent element. If you want to print only specific ones, you can, obviously, add a trivial check like this:
String aName = aNode.getNodeName();
if (aName.equals("taxe")) { // ...
But you can actually filter out the attributes with XPath:
String expression = "//*[ " + element + "]/#*[name() = 'id' or name() = 'taxe']";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
System.out.printf("%s: %s\n", node.getNodeName(), node.getNodeValue());
}
The XPath expression above fetches all attribute nodes having names equal to whether id, or taxe. If you want all attributes, simply remove the last condition:
String expression = "//*[ " + element + "]/#*";
I am trying to parse this particular latitude and longitude string into my XML Parser written in Java, but I am not sure what element to use, as point does not having a closing />
<data>
<location>
<location-key>point1</location-key>
<point latitude="39.95" longitude="-75.17"/>
</location>
<moreWeatherInformation applicable-location="point1">
http://forecast.weather.gov/MapClick.php?textField1=39.95&textField2=-75.17
</moreWeatherInformation>
<time-layout time-coordinate="local" summarization="none">
<layout-key>k-p24h-n1-1</layout-key>
<start-valid-time>2013-10-30T08:00:00-04:00</start-valid-time>
<end-valid-time>2013-10-30T20:00:00-04:00</end-valid-time>
</time-layout>
<time-layout time-coordinate="local" summarization="none">
<layout-key>k-p24h-n2-2</layout-key>
<start-valid-time>2013-10-29T20:00:00-04:00</start-valid-time>
<end-valid-time>2013-10-30T09:00:00-04:00</end-valid-time>
<start-valid-time>2013-10-30T20:00:00-04:00</start-valid-time>
<end-valid-time>2013-10-31T09:00:00-04:00</end-valid-time>
</time-layout>
<parameters applicable-location="point1">
<temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n1-1">
<name>Daily Maximum Temperature</name>
<value>64</value>
</temperature>
<temperature type="minimum" units="Fahrenheit" time-layout="k-p24h-n2-2">
<name>Daily Minimum Temperature</name>
<value>44</value>
<value>52</value>
</temperature>
</parameters>
</data>
Using the code below, I get the following output.
try {
File newXMLFile = new File("H:\\520\\SOAP Data Acquisition\\testNOAA.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(newXMLFile);
doc.getDocumentElement().normalize();
System.out.println("Title: " + doc.getElementsByTagName("title").item(0).getTextContent());
System.out.println("Field: " + doc.getElementsByTagName("field").item(0).getTextContent());
System.out.println("category: " + doc.getElementsByTagName("category").item(0).getTextContent());
System.out.println("Date Created: " + doc.getElementsByTagName("creation-date").item(0).getTextContent());
NodeList nList = doc.getElementsByTagName("data");
for(int i = 0; i < nList.getLength(); i++){
Node nNode = nList.item(i);
System.out.println("\nCurrent Element: " + nNode.getNodeName());
if(nNode.getNodeType() == Node.ELEMENT_NODE){
Element eElement = (Element) nNode;
System.out.println("Location: " + eElement.getAttribute("point"));
System.out.println("Start Time: "+eElement.getElementsByTagName("start-valid-time").item(0).getTextContent());
System.out.println("End Time: "+eElement.getElementsByTagName("end-valid-time").item(0).getTextContent());
System.out.println("");
}
}
}catch(Exception e){
e.printStackTrace();
}
Output:
Title: NOAA's National Weather Service Forecast Data
Field: meteorological
category: forecast
Date Created: 2013-10-29T14:42:58Z
Current Element: data
Location:
Start Time: 2013-10-30T08:00:00-04:00
End Time: 2013-10-30T20:00:00-04:00
For the relevant part of your code try this instead. It's assuming there's only going to be one "point" in the entire "data" tag (or at least, that you're only interested in the first "point"), but it works for what you have posted.
NodeList nList = doc.getElementsByTagName("data");
for(int i = 0; i < nList.getLength(); i++){
Node nNode = nList.item(i);
System.out.println("\nCurrent Element: " + nNode.getNodeName());
if(nNode.getNodeType() == Node.ELEMENT_NODE){
Element eElement = (Element) nNode;
Element point = (Element)(eElement.getElementsByTagName("point").item(0));
System.out.println("Location: " + point.getAttribute("latitude") + ", " + point.getAttribute("longitude"));
System.out.println("Start Time: "+eElement.getElementsByTagName("start-valid-time").item(0).getTextContent());
System.out.println("End Time: "+eElement.getElementsByTagName("end-valid-time").item(0).getTextContent());
System.out.println("");
}
}
I'm working on reading DMX Values from an XML document. The method only returns one node from the element that I'm trying to pull from but there should be 512.
Here is the method:
public static void readXML(int cueNo){
try {
File fXmlFile = new File(MixWindow.Globals.fileLoc);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("Cue");
System.out.println("-----------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = (Node) nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("Cue Name : " + getTagValue("Cue_Name", eElement));
System.out.println("Cue Number : " + getTagValue("Cue_Number", eElement));
//System.out.println("Nick Name : " + getTagValue("nickname", eElement));
//System.out.println("Salary : " + getTagValue("salary", eElement));
}
}
NodeList nListII = doc.getElementsByTagName("DMX");
//nListII = doc.getElementsByTagName("DMX");
System.out.println("-----------------------");
int length = nListII.getLength();
System.out.println("DMX Length: " + length);
for (int tempII = 0; tempII < nListII.getLength(); tempII++) {
Node nNodeII = (Node) nListII.item(tempII);
if (nNodeII.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNodeII;
System.out.println("DMX Chnl: " + getTagValue("DMX_Chnl", eElement));
System.out.println("DMX Val: " + getTagValue("DMX_Val", eElement));
//System.out.println("Nick Name : " + getTagValue("nickname", eElement));
//System.out.println("Salary : " + getTagValue("salary", eElement));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getTagValue(String sTag, Element eElement) {
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
}
Here is a portion of the XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ShowFile>
<Cue>
<Cue_Name>stuff and junk</Cue_Name>
<Cue_Number>1</Cue_Number></Cue>
<DMX>
<DMX_Chnl>1</DMX_Chnl>
<DMX_Val>0</DMX_Val>
<DMX_Chnl>2</DMX_Chnl>
<DMX_Val>0</DMX_Val>
<DMX_Chnl>3</DMX_Chnl>
<DMX_Val>0</DMX_Val>
<DMX_Chnl>4</DMX_Chnl>
<DMX_Val>0</DMX_Val>
......
<DMX_Chnl>512</DMX_Chnl>
<DMX_Val>0</DMX_Val>
System.out created this:
Cue Name : stuff and junk
Cue Number : 1
-----------------------
DMX Length: 1
DMX Chnl: 1
DMX Val : 0
What am I doing wrong?
shortened xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><ShowFile><Cue><Cue_Name>Stuff and Junk</Cue_Name><Cue_Number>1</Cue_Number></Cue><DMX><DMX_Chnl>1</DMX_Chnl><DMX_Val>0</DMX_Val><DMX_Cue>1</DMX_Cue><DMX_Chnl>2</DMX_Chnl><DMX_Val>0</DMX_Val><DMX_Cue>1</DMX_Cue><DMX_Chnl>3</DMX_Chnl><DMX_Val>0</DMX_Val><DMX_Cue>1</DMX_Cue><DMX_Chnl>4</DMX_Chnl></DMX></ShowFile>
added loop:
if (nNodeII.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNodeII;
NodeList childNodes = nNodeII.getChildNodes();
String result = new String();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
String dcName = node.getNodeName();
String dcVal = node.getNodeValue();
System.out.println("DMX stuff: " + dcName + " " + dcVal);
}
}
Java and the XML parser behave correctly.
But you expect the document to have a different structure than it actually does! So you are looking in the wrong place for nodes, and thus not finding nodes there.
There is only one DMX element. You want to enumerate the children, not the DMX elements.
(i.e. you want to have DMX_Chnl elements, and these are not each wrapped in a separate DMX node)
I have the xml file as follows,
<CHPkt xmlns="Smartscript/EmarSchema">
<CHInfo>
<StoreId>1800</StoreId>
<CHId>DB439A79-3D6F-4D25-BE0A-C4692978C072</CHId>
<CHName>Test</CHName>
<Address>
<Address1>Test Address</Address1>
</Address>
<DrugRounds>
<RoundTime>09:00</RoundTime>
<RoundTime>13:00</RoundTime>
<RoundTime>17:00</RoundTime>
</DrugRounds>
</CHInfo>
</CHPkt>
How to get the values of the tags which has the same name, my code is as follows,
public class ReadXml {
public static void main(String[] args){
try{
File xmlFile = new File("/home/jayakumar/Desktop/SmartScript.XML");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlFile);
NodeList nodeList1 = document.getElementsByTagName("CHInfo");
System.out.println("######################################");
for(int i =0;i<nodeList1.getLength();i++){
org.w3c.dom.Node node = nodeList1.item(i);
if(node.getNodeType()== org.w3c.dom.Node.ELEMENT_NODE){
Element element = (Element) node;
System.out.println("StoreId : " + getTagValue("StoreId", element));
System.out.println("CHId : " + getTagValue("CHId", element));
System.out.println("CHName : " + getTagValue("CHName", element));
System.out.println("Address : " + getTagValue("Address1", element));
}
NodeList nodeList2 = document.getElementsByTagName("DrugRounds");
System.out.println("-------------->"+"DrugRounds");
for(int j =0;j<nodeList2.getLength();j++){
org.w3c.dom.Node subNode = nodeList2 .item(j);
Element e = (Element) subNode;
System.out.println("RoundTime : "+getTagValue("RoundTime", e));
System.out.println("RoundTime : "+getTagValue("RoundTime", e));
System.out.println("RoundTime : "+getTagValue("RoundTime", e));
}
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
private static String getTagValue(String sTag, Element element) {
NodeList nlList = element.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
}
I wasn't able to extract the values of second and third Roudtimes.How to parse the tags with same name
Thanks
Why not just check if it has any child nodes then get the value from it
for (int j = 0; j < nodeList2.getLength(); j++) {
org.w3c.dom.Node subNode = nodeList2.item(j);
NodeList childNodes = subNode.getChildNodes();
for(int iDx = 0; iDx < childNodes.getLength(); iDx++){
if(childNodes.item(iDx) instanceof Element){
Element e = (Element) childNodes.item(iDx);
System.out.println("RoundTime : "+ e.getFirstChild().getNodeValue());
}
}
I have xml file
<A>
<A1>
<A2>Hi</A2>
</A1>
<A>
<B>
<B1></B1>
<B2>100</B2>
</B>
<A>
<A1>
<A2>Hello</A2>
</A1>
<A>
<B>
<B1>1000</B1>
<B2></B2>
</B>
likewise this goes more than 10 blocks. Now my java code able to read one by one that is first reads all after that reads tag.
Code:
public class XMLParse {
static Document doc;
public static void main(String argv[]) {
try {
File file = new File("/home/dev042/Desktop/xxx.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element " + doc.getDocumentElement().getNodeName());
NodeList nodeLst = doc.getElementsByTagName("A");
System.out.println("Information of all Balence Sheet");
int count = nodeLst.getLength();
String name;
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElmnt = (Element) fstNode;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("A1");
for(int i =0; i < fstNmElmntLst.getLength(); i++ )
{
Node lst = fstNmElmntLst.item(i);
if(lst.getNodeType() == Node.ELEMENT_NODE)
{
Element fsttravel = (Element) lst;
NodeList secNmElt = fsttravel.getElementsByTagName("*");
name = secNmElt.item(0).getTextContent();
System.out.println("Name : " + name);
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
String amt;
double amount;
NodeList nodeLst = doc.getElementsByTagName("B");
int coun = nodeLst.getLength();
for (int s = 0; s < nodeLst.getLength(); s++) {
Node secNode = nodeLst.item(s);
if (secNode.getNodeType() == Node.ELEMENT_NODE) {
try
{
Element amtval = (Element) secNode;
NodeList secval = amtval.getElementsByTagName("B1");
amt = secval.item(0).getTextContent();
//amount = Double.parseDouble(amt);
System.out.println("SubAmt :" + amt);
NodeList lstNmElmntLst = amtval.getElementsByTagName("B2");
amt = lstNmElmntLst.item(0).getTextContent();
System.out.println("MainAmt : " +amt);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
}
}
current output:
Hi
Hello
100
1000
I want to read the tags alternatively. then only i can able map the values. How can i read these tags alternatively. output should be like this
Hi 100
Hello 1000
Kindly help me out of it.
Thanks in advance..
I think you need to filter only tags so that your parser will fetch only tags.For this you can use XPath.This is an examples here:
http://www.roseindia.net/tutorials/xPath/java-xpath.shtml