I am new developer in java application. I would like to modify an XML file node value. I have used an xml file for modify as follows
<staff id="2">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>2000000</salary>
<age>28</age>
</staff>
in above xml I would like to change salary value as 345375. For this modification I have written code as follows
try{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File("/sdcard/myxml.xml"));
//Get the staff element by tag name directly
Node nodes = doc.getElementsByTagName("staff").item(0);
//loop the staff child node
NodeList list = nodes.getChildNodes();
for (int i =0; i<list.getLength();i++){
Node node = list.item(i);
//get the salary element, and update the value
if("salary".equals(node.getNodeName())){
node.setNodeValue("345375");
}
}
}
catch (Exception e) {
e.printStackTrace();
}
if I use this way that value not modifying salary.
How can I modify an XML node value?
First you have to realize that node.setValue() is modifying the representation that is stored in memory. Knowing that, then you just need to figure out how to write that output to disk. See this, for an example.
node.Text = "Enter your value here"; //This will work
Related
I am new to Android. I have been trying to update a node value of my xml file using DomParser. I have been workin with asset folder xml file to read. I realised asset folder files cannot be updated and then created a raw folder to save my xml file.I have been refering many answers provided by different people for a long time but nothing is workin!
Portion of my .xml file
<events>
<type>ABC</type>
<time>1:30-2:45pm</time>
<day>XYX</day>
<note>123</note>
</events>
and I have been trying the code
try{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
InputStream is = this.getResources().openRawResource(temp1);
Document doc = docBuilder.parse(is);
if (null != doc.getDocumentElement()){
v1.setText("\n\nhiii888",doc.getDocumentElement()); ("HERE")
RelativeLayout layout = (RelativeLayout) findViewById(R.id.content);
layout.addView(v1);
}
Node nodes = doc.getElementsByTagName("events").item(0);
NodeList list = nodes.getChildNodes();
for (int i =0; i<list.getLength();i++){
Node node = list.item(i);
if("type".equals(nodes.getNodeName())){
node.setNodeValue("ABC123");
}
}
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("temp1.xml"));
transformer.transform(source, result);
}
My app shows stopped running when executing this and so I put in the piece of if block with textview and relative layout("mentioned as "HERE") to see where until the code works fine..The getDocumentElement()does return a value and so it displays in textview as
hiii888org.apache.harmony.xml.dom.ElementImpl#e58aa2f
I dont know why this is coming.I also used Text to typecast and retrieve the result and also .toString() function expecting typecasting can solve the problem.Nothing seem to work..Have been trying Xml update now for days...Hope to see answers that can sort my issue regarding xml update other than the already existing ones...Thanks in advance.
So im trying to parse and xml file in android. Bellow is a link to the file and my code. I'm trying to get the current temp stored as "temp_f" in the "current_conditions" element. But every time i run it i get this error, 09-15 20:26:47.359: DEBUG/ErOr(17663): java.lang.ClassCastException: org.apache.harmony.xml.dom.ElementImpl
http://www.google.com/ig/api?weather=10598
DocumentBuilderFactory factory1 = DocumentBuilderFactory.newInstance();
factory1.setNamespaceAware(true); // never forget this!
InputSource source = new InputSource(new StringReader(xmltemp));
Document doc = factory1.newDocumentBuilder().parse(source);
String newstring = "" + ((DocumentBuilderFactory) ((Document) doc.getDocumentElement().
getElementsByTagName("current_conditions").item(0)).
getElementsByTagName("temp_f").item(0)).
getAttribute("data");
Have a look at the Java XPath API -- that should be much nicer than traversing the DOM to find your data:
URL url = new URL("http://www.google.com/ig/api?weather=10598");
InputSource xml = new InputSource(url.openStream());
XPath xpath = XPathFactory.newInstance().newXPath();
String data = xpath.evaluate("//current_conditions/temp_f/#data", xml);
As for the original question:
First put every statement of your extraction code on a line of its own, this will help you a lot with finding the problems (and line numbers in stacktrace will be a lot more precise):
Element docElem = doc.getDocumentElement();
Document curr_cond = (Document) /*1*/ docElem.getElementsByTagName("current_conditions").item(0);
DocumentBuilderFactory temp_f = (DocumentBuilderFactory) /*2*/ curr_cond.getElementsByTagName("temp_f").item(0);
String newstring = "" + temp_f.getAttribute("data");
At /*1*/ you try to cast a org.w3.dom.Node into an org.w3.dom.Document -- but not every Node is a Document, as can be seen by the ClassCastException here: The returned Node is actually an instance of the org.w3.dom.Element interface, more precisely an instance of class of org.apache.harmony.xml.dom.ElementImpl (part of the Apache Harmony XML parser implementation).
So let's remove the cast and change the declared type of curr_cond to Node:
Element docElem = doc.getDocumentElement();
Node curr_cond = docElem.getElementsByTagName("current_conditions").item(0);
DocumentBuilderFactory temp_f = (DocumentBuilderFactory) /*2*/ curr_cond.getElementsByTagName("temp_f").item(0);
String newstring = "" + temp_f.getAttribute("data");
Now a second problem becomes obvious at /*2*/: The Node interface does not specify a getElementsByTagName() method, that's probably why you did try to cast to Document above. This won't compile and there is no way to get it to.
Why you cast the result to DocumentBuilderFactory is beyond me. Yes, there is a getAttribute() method but both the class name and method javadoc should have made clear that it's definitely not doing want you want.
So my above recommendation holds: Please use XPath, it's the better tool for this task :)
There actually is a way to extract the data using only DOM for your first task (current temperature). It relies on the fact that the temp_f element is unique and is a lot more verbose than the above XPath expression, though:
Element docElem = doc.getDocumentElement();
Node temp_f = docElem.getElementsByTagName("temp_f").item(0);
NamedNodeMap attributes = temp_f.getAttributes();
Node dataAttr = attributes.getNamedItem("data");
String data = dataAttr.getNodeValue();
i would like modify text of xml tag value i have used an xml as follows
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
here i would like to change the from name Jani as prasad.how can i chage that by using java code
i have written a java code as follows
try{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File("/mnt/sdcard/one.xml"));
//Get the staff element by tag name directly
Node nodes = doc.getElementsByTagName("note").item(0);
//loop the staff child node
NodeList list = nodes.getChildNodes();
for (int i =0; i<list.getLength();i++){
Node node = list.item(i);
//get the salary element, and update the value
if("from".equals(nodes.getNodeName())){
node.setNodeValue("prasad");
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/mnt/sdcard/one.xml"));
transformer.transform(source, result);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
There is problem in your code: "Jani" is a text node with parent element node "from". So you should change value of the text node.
...
for (int i =0; i<list.getLength();i++) {
Node node = list.item(i);
//get the salary element, and update the value
if("from".equals(node.getNodeName())){
Text text = (Text) ((Element) node).getChildNodes().item(0);
text.setNodeValue("prasad");
}
}
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/mnt/sdcard/one.xml"));
transformer.transform(source, result);
...
And I think RegExp would be much easier for this task
"your xml as string".replaceAll("<from>.*?</from>", "<from>prasad</from>");
There are several different examples available.
Writing XML on Android This seems to have the best samples.
Other hits:
How to rewrite or modify XML in android 2.1 version
Load and modify xml file in Android
I am parsing a xml from an url.The url is has mobile IMEI no and searchstring based on my application. i put my xml parsing code in android project it does not work. but if i run as separate java program it is working. please help me.
Log.e("rsport-", "function1");
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setCoalescing(true); // Convert CDATA to Text nodes
factory.setNamespaceAware(false); // No namespaces: this is default
factory.setValidating(false); // Don't validate DTD: also default
DocumentBuilder parser = factory.newDocumentBuilder();
Log.e("rsport-", "function2");
Document document = parser.parse("http://demo.greatinnovus.com/restingspot/search?userid=xxxxxxxxxxxxxxxx&firstname=a&lastname=a");
Log.e("rsport-","function3");
NodeList sections = document.getElementsByTagName("Searchdata");
int numSections = sections.getLength();
for (int i = 0; i < numSections; i++)
{
Element section = (Element) sections.item(i);
if(section.hasChildNodes()==true){
NodeList section1=section.getChildNodes();
for(int j=0;j<section1.getLength();j++){
if(section1.item(j).hasChildNodes()==true) {
for(int k=0;k<section1.item(j).getChildNodes().getLength();k++)
xmlvalue=String.valueOf(section1.item(j).getChildNodes().item(k).getNodeValue()).trim();
arl.add(xmlvalue);
}
}
}
}
}
}
catch(Exception e){}
System.out.println("id"+id+" searchdatacount"+searchdatacount);
System.out.println("---------");
ListIterator<String> litr = arl.listIterator();
while (litr.hasNext()) {
String element = litr.next();
Log.e("rsport-", "elememt");
}
after the Log.e("rsport-", "function2"); does not work.
Refer my blog, i had gave Detailed explanation, http://sankarganesh-info-exchange.blogspot.com/2011/04/parsing-data-from-internet-and-creating.html, and make sure , that you had add the Internet permission in your Manifest file.
If you had gone through Myblog, then you will able to notice that you did the following line as wrong
Document document = parser.parse("http://demo.greatinnovus.com/restingspot/search?userid=xxxxxxxxxxxxxxxx&firstname=a&lastname=a");
use like this
URL url =new URL("http://demo.greatinnovus.com/restingspot/search?userid=xxxxxxxxxxxxxxxx&firstname=a&lastname=a");
Document document= parser.parse(new InputSource(url.openStream()));
I'm using the DOM parser to retrive information from a XML file that looks like this:
<data>
<metData>
<wantedInformation>
</metData>
<metData>
<Information>
</metData>
<metData>
<Information>
</metData>
<data>
The problem is because I don't know how to parse only the first part of <metData>. I don't need the second and the third part, but the parser displays them anyway.
The xml file is from a weather forcast site:
http://www.meteo.si/uploads/probase/www/fproduct/text/sl/fcast_SLOVENIA_MIDDLE_latest.xml
and I need just the following line: <nn_shortText>oblačno</nn_shortText>
Pls take care whether your XML file is well formed or not,
You have to the notice three methods which i had shown below, they are
1. getElementsByTagName - Mention the tag which you want to parse
2.getChildNodes - retervies the child node
3.getNodeValue()- with the help of this method you can access the
value of particular tag
Step 1: Create a Method to parse _Information_Value ,inorder to parse the data of Information tag
String[] infoId=null;
public void parse_Information_Value() throws UnknownHostException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
org.w3c.dom.Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("metData");
int a=items.getLength();
int k=0;
for (int i = 0; i < items.getLength(); i++) {
Message_category message = new Message_category();
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for (int j = 0; j < properties.getLength(); j++) {
Node property = properties.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase("wantedInformation")) {
message.setId(property.getFirstChild()
.getNodeValue());
infoId[k]=property.getFirstChild().getNodeValue();
k++;
}
}
}
} catch (Exception e) { }
}
Depending on the size of your document, you may also want to use at a streaming oriented parser like SAX or Stax, which does not pull the whole document into memory and thus needs less memory than DOM.
Good thing is that SAX is already built into Android, so you can use it right away.
See this link for a usage example.