Based on several examples here on StackOverflow I have the following code for indenting XML.
I have a source xml file in a String. Output however is not indented, but it also doesn't give any errors. Output is checked in the debugger, and doesn't contain any characters like spaces or tabs, that could be rendered wrongly and thus overlooked.
String input = "xmldata";
Source xmlInput = new StreamSource(new StringReader(input));
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
return stringWriter.toString();
I have also tried setting indent-amount to "2", but then the app would complain about a unknown attribute. Probably this is not implemented in Android.
Am I doing something wrong here? Are there other options for generating a indented xml file from a source xml string?
You can try something like this:
String input = "xmldata";
InputSource is = new InputSource(new StringReader(input));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().parse(is);
System.out.println(prettyPrint(doc));
public static final String prettyPrint(Node xml) throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException {
StringWriter stringWriter = new StringWriter();
StreamResult out = new StreamResult(stringWriter);
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.transform(new DOMSource(xml), out);
return out.getWriter().toString();
}
Related
I have a problem in DOM parsing Arabic letters, I got weird characters. I've tried changing to different encoding but I couldn't.
the full code is on this link: http://test11.host56.com/parser.java
public Document getDomElement(String xml) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
Reader reader = new InputStreamReader(new ByteArrayInputStream(
xml.getBytes("UTF-8")));
InputSource is = new InputSource(reader);
DocumentBuilder db = dbf.newDocumentBuilder();
//InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
return doc;
}
}
my xml file
<?xml version="1.0" encoding="UTF-8"?>
<music>
<song>
<id>1</id>
<title>اهلا وسهلا</title>
<artist>بكم</artist>
<duration>4:47</duration>
<thumb_url>http://wtever.png</thumb_url>
</song>
</music>
You already have the xml as String, so unless that string already contains the odd characters (that is, it has been read in with the wrong encoding), you can avoid encoding madness here by using a StringReader instead; e.g. instead of:
Reader reader = new InputStreamReader(new ByteArrayInputStream(
xml.getBytes("UTF-8")));
use:
Reader reader = new StringReader(xml);
Edit: now that I see more of the code, it seems the encoding issue already happend before the XML is parsed, because that part contains:
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
The javadoc for the EntityUtils.toString says:
The content is converted using the character set from the entity (if any), failing that, "ISO-8859-1" is used.
It seems the server does not send the proper encoding information with the entity, and then the HttpUtils uses a default, which is not UTF-8.
Fix: use the variant that takes an explicit default encoding:
xml = EntityUtils.toString(httpEntity, "utf-8");
Here I assume the server sends UTF-8. If the server uses a different encoding, that one should be set instead of UTF-8. (However as the XML also declares encoding="UTF-8" I thought this is the case.) If the encoding the server uses is not known, then you can only resort to wild guessing and are out of luck, sorry.
If the XML contains Unicode characters such as Arabic or Persian letters, StringReader would make an exception. In these cases, pass the InputStream straightly to the Document object.
I would like to change the values of RouteName node, according to the below code, I have studied some tutorials and applied it. Am I on the right way? what did I miss?
try{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(Environment.getExternalStorageDirectory()+"/Trip/"+tripID+".trip"));
Node nodes = doc.getElementsByTagName("RouteName").item(0);
//newname is String variable which retrive value from edite text box
nodes.setNodeValue(newname);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(Environment.getExternalStorageDirectory()+"/Trip/"+tripID+".trip"));
transformer.transform(source, result);
}
catch (Exception e) {
e.printStackTrace();
}
you are writing/setting new value to dom object, which is not a physical file/document, if you want to reflect the changes to the filesystem, you need to write new contents on FileOutputStream.
Xml parsing api is throwing sax parse exception, If i try to parse a xml file which has attributes at root node.
One thing i have noticed is that, this happens if there is a UTF-8 BOM character at the start of the string, if i remove the BOM character things work fine. This code is working fine on 3.0 sdk and below, i saw this problem only in 3.1
am using following parser:
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = docFactory.newDocumentBuilder();
Document doc = null;
StringReader sr = new StringReader(xmlString);
InputSource is = new InputSource(sr);
doc = builder.parse(is);
Try this:
public Document parse(String xml) throws ParsingFailedException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//encode the xml to UTF -8
ByteArrayInputStream encXML = new ByteArrayInputStream(xml.getBytes("UTF8"));
Document doc = builder.parse(encXML);
log.error("XML parsing OK");
return doc;
} catch (Exception e) {
log.error("Parser Error:" + e.getMessage());
throw new ParsingFailedException("Failed to parse XML : Document not well formed", e);
}
}
Thanks evilone,
I have opened a issue with google, and they will be fixing this in their branch.
http://code.google.com/p/android/issues/detail?id=16892
Comments from google developer:
"I've prepared a fix for the root problem in our internal Honeycomb tree. But you don't need the fix for your code. Your parseXml method should just take an InputStream rather than a String. You can pass that directly to the InputSource constructor."
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
//here append some children....
(this application should run on andoroid API 4)
the problem is : how can I get the text content(including markup) of the "doc" ?
I will appreciated if someone can give me some advice. Thanks~!
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
t.transform(new DOMSource(d), new StreamResult(sw));
System.out.println(sw.toString());
I use the following code to parse the XML file.
DocumentBuilderFactory factory;
DocumentBuilder builder;
InputStream is;
Document dom;
try {
factory = DocumentBuilderFactory.newInstance();
is = new FileInputStream(strFileName);
builder = factory.newDocumentBuilder();
dom = builder.parse(is);
}
catch(Exception e){}
Instead of XML file is there any way to parse the String.
String xml="<?xml version="1.0"?> <name> Application</name> <demo> Demo </demo> </xml>";
You can convert your string to an InputStream using ByteArrayInputStream:
String xml ="valid xml here";
InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
dom = builder.parse(is);
You can use StringReader :
StringReader sr = new StringReader(xml);
InputSource is = new InputSource(sr);
Document d = builder.parse(is);