Java:XML Parsing - java

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());
}
}

Related

Java XML removeChild not working?

Hello so i've looked this question up alot but I couldn't find a solution that worked. I'm basically trying to remove the "job" node as seen declared in line 7 and removed in line 13. There's 0 runtime errors but the node doesn't get removed.
NodeList rootNodes = xml.getElementsByTagName("jobs");
Node rootNode = rootNodes.item(0);
Element rootElement = (Element) rootNode;
NodeList jobsList = rootElement.getElementsByTagName("job");
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
if(jobElement.getAttribute("id").equals(
msgEvent.getMessage().getContentRaw().split(" ")[2]))
{
rootNode.removeChild(job);
msgEvent.getChannel().sendMessage("Removed Job " + jobElement.getAttribute("id") + " (Summary: '" + jobElement.getAttribute("summary") + "')").complete();
}
}
Here's the XML
<?xml version = "1.0"?>
<jobs>
<job payment = "50000" poster="171048434529337344" collect = "asdf" id = "1" summary="asdfd" expires="5/10/18"> </job>
<job payment = "10000" poster="171048434529337344" collect = "asdf" id = "2" summary="asdf" expires="5/10/18"> </job>
</jobs>
since this is too large for comment, Here is my test code and results:
public static void main(String[] args) {
try (InputStream is = Files.newInputStream(Paths.get("C://Temp/xx.xml"))) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document xml = builder.parse(new InputSource(is));
NodeList rootNodes = xml.getElementsByTagName("jobs");
Node rootNode = rootNodes.item(0);
Element rootElement = (Element) rootNode;
NodeList jobsList = rootElement.getElementsByTagName("job");
System.out.println("list before removal");
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
System.out.println(jobElement.getAttribute("id"));
}
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
if (jobElement.getAttribute("id").equals("1")) {
rootNode.removeChild(job);
}
}
System.out.println("list after removal");
jobsList = rootElement.getElementsByTagName("job");
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
System.out.println(jobElement.getAttribute("id"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
output:
list before removal
1
2
list after removal
2

Iterating only one xml tag using Java

I'm iterating an XML object, but its fetching only one XML tag value. Please check the code. It is printing only the first tag value "abd5fd81-2bd6-4479-9d60-61fe533a13b7".
public class sample {
/**
* #param args
*/
private final static String XML_DATA = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<list>" +
"<string>abd5fd81-2bd6-4479-9d60-61fe533a13b7</string>" +
"<string>e127393b-343b-433c-87fc-27289758cca8</string>" +
"<string>753f79fe-a1d2-4383-b5c9-3ec8aa6b7e65</string>" +
"<string>2c71f819-65a6-4b08-8870-e71b1c770992</string>" +
"<string>ad22d8c0-8187-4243-8189-92e94c969208</string>" +
"<string>e6e70ab9-6149-4dfd-9d88-e27ec419847e</string>" +
"<string>87d8566b-4c8a-4ef0-9fa9-c7b8805e5631</string>" +
"<string>1309a729-20b4-40bb-96c8-46c96f205e60</string>" +
"<string>5e78b822-d472-4f02-859d-de36183c5d01</string>" +
"<string>410c70fb-8b05-47ef-bfbf-29284e45c8d3</string>" +
"</list>";
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
// TODO Auto-generated method stub
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
builder = factory.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(XML_DATA));
Document doc = builder.parse(is);
NodeList nodes = doc.getElementsByTagName("list");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("string");
Element line = (Element) name.item(0);
System.out.println("String: " + getCharacterDataFromElement(line));
}
}
private static String getCharacterDataFromElement(Element e) {
// TODO Auto-generated method stub
Node child = e.getFirstChild();
if (child instanceof org.w3c.dom.CharacterData) {
org.w3c.dom.CharacterData cd = (org.w3c.dom.CharacterData) child;
return cd.getData();
}
return "?";
}
}
Is there anything missing in the code?
Because I don't have a compiler ready right now, I do not know for sure if this is perfect. Try it and report back:
....
Document doc = builder.parse(is);
NodeList nodes = doc.getElementsByTagName("list");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("string");
for (int x = 0; x < name.getLength(); x++) {
Element line = (Element) name.item(x);
System.out.println("String: " + getCharacterDataFromElement(line));
}
}
....
I think that should be what you are after.
You're reading just first string:
NodeList name = element.getElementsByTagName("string");
Element line = (Element) name.item(0); ### LOOP INSTEAD OF GETTING item(0)
To read all of them you have to loop over all nodes from name, similarly what you did in outer for loop:
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("string");
for (int j = 0; j < name.getLength(); j++) {
Element line = (Element) name.item(j);
System.out.println("String: " + getCharacterDataFromElement(line));
}
}

xml routine not processing the child nodes I want

<report id="oleg">
<title>olegitimerade rapport</title>
<id_email>joch1</id_email>
<id_email>kang15</id_email>
</report>
I am using the following code with the DOM XML parser to extract the above list an xml file.
String tag = "report";
String[] elementTags = new String[] {"title", "id_email"};
NodeList nList = this.doc.getElementsByTagName(tag);
try{
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
HashMap<String, String> attribute = new HashMap<String, String>();
Element eElement = (Element) nNode;
if(eElement.hasAttribute("id")){
String id = eElement.getAttribute("id");
attribute.put("id", id);
for (String elementTag : elementTags){
try{
int index=0;
while(null!=eElement.getElementsByTagName(elementTag).item(index).getTextContent()){
attribute.put(elementTag, eElement.getElementsByTagName(elementTag).item(index).getTextContent());
index++;
}
}catch (Exception e){
//System.out.println("id : "+id+" - Attribute element '"+ elementTag+ "' not found in XML! ["+this.xmlFile+"]");
}
}
attributes.add(attribute);
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
The problem is when I get the multiple tags....I cannot extract the 2nd ID (kang15).
Clearly the while loop is incorrect, so I need a little help here fixing the issue.
while(null!=eElement.getElementsByTagName(elementTag).item(index).getTextContent()){
attribute.put(elementTag, eElement.getElementsByTagName(elementTag).item(index).getTextContent());
index++;
}
Consider using XPath for this:
XPath xpath = XPathFactory
.newInstance()
.newXPath();
Element report = (Element) xpath.evaluate("//report", doc, XPathConstants.NODE);
String id = xpath.evaluate("#id", report);
String title = xpath.evaluate("title", report);
NodeList emails = (NodeList)
xpath.evaluate("id_email/text()", report, XPathConstants.NODESET);
System.out.println(id);
System.out.println(title);
for(int i=0; i<emails.getLength(); i++) {
System.out.println(emails.item(i).getTextContent());
}

Why is this Java method not returning all XML Elements?

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)

How to read alternative tags in xml using java?

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

Categories