Java XML removeChild not working? - java

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

Related

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

How to parse xml in android-java?

In my application, I have an XML file and I want to parse the XML file and extract data from the XML tags. Here is my XML file.
<array>
<recipe>
<name> Crispy Fried Chicken </name>
<description> Deliciously Crispy Fried Chicken</description>
<prepTime>1.5 hours </prepTime>
<instructions>instruction steps</instructions>
<ingredients>
<item>
<itemName>Chicken Parts</itemName>
<itemAmount>2 lbs</itemAmount>
</item>
<item>
<itemName>Salt & Peppers</itemName>
<itemAmount>As teste</itemAmount>
</item>
</ingredients>
</recipe>
<recipe>
<name> Bourben Chicken </name>
<description> A good recipe! A tad on the hot side!</description>
<prepTime>1 hours </prepTime>
<instructions>instruction steps</instructions>
<ingredients>
<item>
<itemName>Boneless Chicken</itemName>
<itemAmount>2.5 lbs</itemAmount>
</item>
<item>
<itemName>Olive Oil</itemName>
<itemAmount>1 -2 tablespoon</itemAmount>
</item>
<item>
<itemName>Olive Oil</itemName>
<itemAmount>1 -2 tablespoon</itemAmount>
</item>
</ingredients>
</recipe>
</array>
I have used DOM parser to parse the above xml file and I have extracted data from <name>, <description>, <prepTime> and <instructions> tags BUT I don't know how to extract data from <ingredients> TAG. You can see my code that I have developed for DOM parser. Here is my DOM parser
public class DOMParser
{
// parse Plist and fill in arraylist
public ArrayList<DataModel> parsePlist(String xml)
{
final ArrayList<DataModel> dataModels = new ArrayList<DataModel>();
//Get the xml string from assets XML file
final Document doc = convertStringIntoXML(xml);
// final NodeList nodes_array = doc.getElementsByTagName("array");
//Iterating through the nodes and extracting the data.
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node = nodeList.item(i);
if (node instanceof Element)
{
DataModel model = new DataModel();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++)
{
Node cNode = childNodes.item(j);
if (cNode instanceof Element)
{
String content = cNode.getLastChild().getTextContent().trim();
if(cNode.getNodeName().equalsIgnoreCase("name"))
model.setName(content);
else if(cNode.getNodeName().equalsIgnoreCase("description"))
model.setDescription(content);
else if(cNode.getNodeName().equalsIgnoreCase("prepTime"))
model.setPrepTime(content);
else if(cNode.getNodeName().equalsIgnoreCase("instructions"))
model.setInstructions(content);
}
}
dataModels.add(model);
}
}
return dataModels;
}
// Create xml document object from XML String
private Document convertStringIntoXML(String xml)
{
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
}
catch (ParserConfigurationException e)
{
System.out.println("XML parse error: " + e.getMessage());
return null;
}
catch (SAXException e)
{
System.out.println("Wrong XML file structure: " + e.getMessage());
return null;
}
catch (IOException e)
{
System.out.println("I/O exeption: " + e.getMessage());
return null;
}
return doc;
}
}
You need to iterate ingredients child nodes like you do it for recipe tag.
But the more easy way is to use XPath.
you can change your code as below.
public ArrayList<DataModel> parsePlist(String xml)
{
final ArrayList<DataModel> dataModels = new ArrayList<DataModel>();
//Get the xml string from assets XML file
final Document doc = convertStringIntoXML(xml);
//final NodeList nodes_array = doc.getElementsByTagName("array");
//Iterating through the nodes and extracting the data.
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node = nodeList.item(i);
if (node instanceof Element)
{
DataModel model = new DataModel();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++)
{
Node cNode = childNodes.item(j);
if (cNode instanceof Element)
{
String content = cNode.getLastChild().getTextContent().trim();
if(cNode.getNodeName().equalsIgnoreCase("name"))
model.setName(content);
else if(cNode.getNodeName().equalsIgnoreCase("description"))
model.setDescription(content);
else if(cNode.getNodeName().equalsIgnoreCase("prepTime"))
model.setPrepTime(content);
else if(cNode.getNodeName().equalsIgnoreCase("instructions"))
model.setInstructions(content);
else if(cNode.getNodeName().equalsIgnoreCase("ingredients"))
{
Element ingredEle = (Element)cNode;
NodeList ingredList = ingredEle
.getElementsByTagName("ingredients");
for (int i = 0; i < ingredList.getLength(); i++)
{
Element item = (Element)ingredList.item(i);
if(item.hasChildNodes())
{
NodeList itemList = item.getElementsByTagName("item");
for (int j = 0; j < itemList.getLength(); j++)
{
Element itemEle = (Element)itemList.item(j);
if (getNodeValue(itemEle, "itemName") != null)
{
String name = getNodeValue(itemEle, "itemName");
//set name here
}
if (getNodeValue(itemEle, "itemAmount") != null)
{
String amount = getNodeValue(itemEle,"itemAmount");
//set amount here
}
}
}
}
}
}
dataModels.add(model);
}
}
return dataModels;
}
private String getNodeValue(Element element, String elementTemplateLoc) {
NodeList nodes = element.getElementsByTagName(elementTemplateLoc);
return getTextNodeValue(nodes.item(0));
}
Hope this will work for you

Android xml parsing based on selection of item [duplicate]

Hi i want to parse XML and display list based on selection of user
my xml is looking like this
below is my code
try {
XMLParser parser = new XMLParser();
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList n1 = doc.getElementsByTagName("company");
// looping through all item nodes <item>
for (int i = 0; i < n1.getLength(); i++) {
// creating new HashMap
Element e = (Element) n1.item(i);
System.out.println("name node "+parser.getValue(e, "name"));
}
by this way i am getting the output like
Company ABC
Company XYZ
of Companies list
but
i would write code like
NodeList n1 = doc.getElementsByTagName("province");
// looping through all item nodes <item>
for (int i = 0; i < n1.getLength(); i++) {
// creating new HashMap
Element e = (Element) n1.item(i);
System.out.println("name node "+parser.getValue(e, "name"));
}
i am getting list of province name
Alberta
Ontario
New York
Florida
but it should work like this
when i select Company ABC
only two provision list should display
Alberta
Ontario
not should all display can any body help me how to rewrite my code
This should do it:
XMLParser parser = new XMLParser();
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList n1 = doc.getElementsByTagName("company");
// looping through all item nodes <item>
for (int i = 0; i < n1.getLength(); i++) {
Element e = (Element) n1.item(i);
System.out.println("name node " +parser.getValue(e, "name"));
NodeList children = e.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
Node child = children.item(j);
if (child.getNodeName().equalsIgnoreCase("province")) {
System.out.println("name node " + parser.getValue((Element)child, "name"));
}
}
}
Use Node.getChildNodes() over the "company" nodes. Then, to get the child province nodes, compare by name. Example:
XMLParser parser = new XMLParser();
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList n1 = doc.getElementsByTagName("company");
// looping through all item nodes <item>
for (int i = 0; i < n1.getLength(); i++) {
Node companyNode = n1.item(i);
NodeList childNodes = companyNode.getChildNodes();
// Here we're getting child nodes inside the company node.
// Only direct childs will be returned (name and province)
for (int j = 0; j < childNodes.getLength(); j++) {
Node childNode = childNodes.item(j);
if("province".equalsIgnoreCase(childNode.getName())){
//Do something with province
}
}
}
Try the following code:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Create a new layout to display the view */
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
/** Create a new textview array to display the results */
TextView name[];
TextView website[];
TextView category[];
try {
URL url = new URL(
"http://xyz.com/aa.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
/** Assign textview array lenght by arraylist size */
name = new TextView[nodeList.getLength()];
website = new TextView[nodeList.getLength()];
category = new TextView[nodeList.getLength()];
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
name[i] = new TextView(this);
website[i] = new TextView(this);
category[i] = new TextView(this);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("name");
Element nameElement = (Element) nameList.item(0);
nameList = nameElement.getChildNodes();
name[i].setText("Name = "
+ ((Node) nameList.item(0)).getNodeValue());
NodeList websiteList = fstElmnt.getElementsByTagName("website");
Element websiteElement = (Element) websiteList.item(0);
websiteList = websiteElement.getChildNodes();
website[i].setText("Website = "
+ ((Node) websiteList.item(0)).getNodeValue());
category[i].setText("Website Category = "
+ websiteElement.getAttribute("category"));
layout.addView(name[i]);
layout.addView(website[i]);
layout.addView(category[i]);
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Set the layout view to display */
setContentView(layout);
}
}
The getElementsBytagName called on the document object will always return the list of all the nodes with the given tag name in the whole document. Instead, filter out the single company element you are interested in, and then call getElementsByTagName on it. E.g.
Element companyEl = doc.getElementById(desiredCompanyId);
if (companyEl != null) { // always good to check
NodeList n1 = companyEl.getElementsByTagName("province");
// your code here
}
Try with this code
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
name[i] = new TextView(this);
website[i] = new TextView(this);
category[i] = new TextView(this);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("name");
Element nameElement = (Element) nameList.item(0);
nameList = nameElement.getChildNodes();
name[i].setText("Name = "
+ ((Node) nameList.item(0)).getNodeValue());
NodeList websiteList = fstElmnt.getElementsByTagName("website");
Element websiteElement = (Element) websiteList.item(0);
websiteList = websiteElement.getChildNodes();
website[i].setText("Website = "
+ ((Node) websiteList.item(0)).getNodeValue());
category[i].setText("Website Category = "
+ websiteElement.getAttribute("category"));
layout.addView(name[i]);
layout.addView(website[i]);
layout.addView(category[i]);
}

Java:XML Parsing

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

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