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.
I try to use dom parser get value from a xml file like:
InputStream inputStream = new ByteArrayInputStream(
xml_string.getBytes());
Document pdom = pbuilder.parse(inputStream);
Element proot = pdom.getDocumentElement();
NodeList pitems = proot.getElementsByTagName("Profile");
But the pitems size is 0, actually, The code above is working in version before 4.0.
So i hope i can get the the name and ismember item.
Don't know how to get it now.
Pls help me.
the xml formate:
<Profile parameter="S...J">
<Name>Jon</Name>
<IsMember>true</Ismember>
</Profile>
You need to change your XML like this
<root>
<Profile parameter="SJ">
<Name>Jon</Name>
<IsMember>true</IsMember>
</Profile>
</root>
and then all other things will work fine
Do this way:
Document pdom = pbuilder.parse(inputStream);
Element proot = pdom.getDocumentElement();
proot.normalize(); //must call
NodeList pitems = document.getElementsByTagName("Profile"); //get element from document
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 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
I created an XML document using Java in my android application. I have to call a web service in my application and pass this XML as an argument there. But my problem is there created a white space between each tag in the XML.
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element root = doc.createElement("subscriber");
doc.appendChild(root);
//creating child node for username
EditText txtusername=(EditText)findViewById(R.id.txtUserName);
subscriber[0]=String.valueOf(txtusername.getText());
Element UserName=doc.createElement("UserName");
UserName.setTextContent(subscriber[0]);
root.appendChild(UserName);
//creating child node for PASSWORD
EditText txtPassword=(EditText)findViewById(R.id.txtPassword);
subscriber[1]=String.valueOf(txtPassword.getText());
Element Password=doc.createElement("Password");
Password.setTextContent(subscriber[1]);
root.appendChild(Password);
//set up a transformer
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
//create string from xml tree
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
String xmlString =sw.toString();
url = new URL("http://192.168.70.14/NewsLetter/subscribing.php?register= " + xmlString);
conn = (HttpURLConnection) url.openConnection();
conn.addRequestProperty("Content-Type", "text/xml; charset=UTF-8");
dis = conn.getInputStream();
The XML is:
<subscriber> <UserName>miya</UserName> <Password>today</Password> </subscriber>
Please give the solution for how to remove the white spaces between the UserName and Password tags.
Of course, it depends on your XML itself. However, you could try using regular expressions.
As an example:
yourXmlAsString.replaceAll(">[\\s\r\n]*<", "><");
Would remove all whitespace between every XML element.
Method documentBuilderFactory.setIgnoringElementContentWhitespace() controls whitespace creation. Use this before you create a DocumentBuilder.
dbfac.setIgnoringElementContentWhitespace(true);
I was able to remove whitespace/tabs/newlines from my transformation using the following property:
transformer.setOutputProperty(OutputKeys.INDENT, "no");
You had it set to yes. I'm sure this question is old enough that it doesn't matter now; but if anyone runs into this in the future, setting the property to no saved me.
This is the regular expression (?:>)(\s*)<
When you use it in the code for Java use
"(?:>)(\\s*)<" and replace with "><"
String xmlString = "<note> <to>Tove</to> <from>Jani</from <heading>Reminder</heading> <title>Today</title> <body>Don't forget me this weekend!</body> </note>";
String str = xmlString.replaceAll("(?:>)(\\s*)<", "><");
This will remove the spaces between the tags and maintain the spaces for the value.
Input:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading> <title>Today</title>
<body>Don't forget me this weekend!</body>
</note>
Output:
<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><title>Today</title><body>Don't forget me this weekend!</body></note>
None of the other answers worked for me. I had to use the below code, to remove both additional whitespaces and new lines.
xmlString.trim().replace("\n", "").replaceAll("( *)<", "<")
This worked for me, thank you. As a caveat, although this is actually useful for my purpose, I noticed that it can also remove text content if that consists only of whitespace. For example, running the following:
String xmlIn = "<tag> </tag> <tag>\t</tag>\t <tag>\r\n</tag><tag> text </tag>";
String xmlOut = xmlIn.replaceAll("(?:>)(\\s*)<", "><");
System.out.println(xmlOut);
gives the following:
<tag></tag><tag></tag><tag></tag><tag> text </tag>
You can create a copy of all nodes in a document, and trims the nodeValue of each node if it exists.
const copyChildrenNodesWithoutWhiteSpace = (document) => {
const clone = document.cloneNode();
for (const child of document.childNodes) {
const childCopy = copyChildrenNodesWithoutWhiteSpace(child);
clone.appendChild(childCopy);
if (childCopy.nodeValue) {
childCopy.nodeValue = childCopy.nodeValue.trim();
}
}
return clone;
};
const result = copyChildrenNodesWithoutWhiteSpace(anyDocument);