給定org.w3c.dom.Document
的實例,如何將其內容保存到文件/流?在Android上書寫XML
編輯: 正如CommonsWare指出的那樣,在Android 2.2之前(API 8)使用Android SDK的類沒有這種可能性。你可以推薦一個第三方庫來保存Document
內容到文件/流?
給定org.w3c.dom.Document
的實例,如何將其內容保存到文件/流?在Android上書寫XML
編輯: 正如CommonsWare指出的那樣,在Android 2.2之前(API 8)使用Android SDK的類沒有這種可能性。你可以推薦一個第三方庫來保存Document
內容到文件/流?
您可以像所有其他文本文件一樣編寫xml。 爲了解析文檔字符串我用:
public static String getStringFromNode(Node root) throws IOException {
StringBuilder result = new StringBuilder();
if (root.getNodeType() == 3)
result.append(root.getNodeValue());
else {
if (root.getNodeType() != 9) {
StringBuffer attrs = new StringBuffer();
for (int k = 0; k < root.getAttributes().getLength(); ++k) {
attrs.append(" ").append(
root.getAttributes().item(k).getNodeName()).append(
"=\"").append(
root.getAttributes().item(k).getNodeValue())
.append("\" ");
}
result.append("<").append(root.getNodeName()).append(" ")
.append(attrs).append(">");
} else {
result.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
}
NodeList nodes = root.getChildNodes();
for (int i = 0, j = nodes.getLength(); i < j; i++) {
Node node = nodes.item(i);
result.append(getStringFromNode(node));
}
if (root.getNodeType() != 9) {
result.append("</").append(root.getNodeName()).append(">");
}
}
return result.toString();
}
但還有一個更簡單的方法來做到這一點: http://www.ibm.com/developerworks/opensource/library/x-android/index.html#list11
private String writeXml(List<Message> messages){
XmlSerializer serializer = Xml.newSerializer();
StringWriter writer = new StringWriter();
try {
serializer.setOutput(writer);
serializer.startDocument("UTF-8", true);
serializer.startTag("", "messages");
serializer.attribute("", "number", String.valueOf(messages.size()));
for (Message msg: messages){
serializer.startTag("", "message");
serializer.attribute("", "date", msg.getDate());
serializer.startTag("", "title");
serializer.text(msg.getTitle());
serializer.endTag("", "title");
serializer.startTag("", "url");
serializer.text(msg.getLink().toExternalForm());
serializer.endTag("", "url");
serializer.startTag("", "body");
serializer.text(msg.getDescription());
serializer.endTag("", "body");
serializer.endTag("", "message");
}
serializer.endTag("", "messages");
serializer.endDocument();
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
感謝您的回答。我知道我可以自己遍歷文檔,但我寧願不要這樣做。您發佈的代碼看起來沒有生產就緒/可靠:/ – 2010-02-19 13:28:12
此代碼僅爲示例,不適用於生產:) – Dmytro 2010-02-19 14:59:39
getStringFromNode()函數完美適用於基本XML內容(未針對複雜XML進行測試),非常感謝。當TransformerFactory無法使用時,這對Android版本有很大的幫助。 – 2012-09-27 12:17:28
有從帶註釋的Java讀取一個非常輕量級的框架和編寫XML對象。它完全兼容Android。
我試過這個框架,它在android上很棒。它確實使用了反思,但這可能不會成爲大多數情況下的問題。 – Qberticus 2010-05-04 17:50:56
它確實使用了反射,但是僅基於註釋的類來執行一次掃描XML模式的反射。所有反射都緩存以提高性能。它比類似JAXB和XStream的框架速度更快,在許多情況下甚至比原生Java XML序列化還要快。 – 2010-05-31 14:14:33
真棒lib,這是我現在使用的。實際上,我將它與ORMLite結合使用,並且我只用了幾個類,所有這些都用這兩個庫進行了註釋,並且我可以從XML中反序列化並使用幾行代碼保存到SQLite。太棒了:) – Adam 2011-09-02 16:50:45
由於API級別8,你可以使用:
javax.xml.transform.TransformerFactory factory = new javax.xml.transform.TransformerFactory();
javax.xml.transform.Transformer transformer = factory.newTransformer();
javax.xml.transform.dom.DOMSource domSource = new javax.xml.transform.dom.DOMSource(rootNode);
javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(outputStream);
transformer(domSource, result);
我的應用程序定位API 4級 – 2010-08-23 22:05:10
我知道艾薩克使用API級別4尋找解決的辦法,但對於其他人誰可以使用最小的8級,這裏是基於關閉的有什麼很好的解決方案拉狄克-K貼:
StringOutputStream.java:
import java.io.OutputStream;
class StringOutputStream extends OutputStream
{
private StringBuilder m_string;
StringOutputStream()
{
m_string = new StringBuilder();
}
@Override
public void write(int b) throws IOException
{
m_string.append((char) b);
}
@Override
public String toString()
{
return m_string.toString();
}
}
XMLHelper.java:
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
public class XMLhelper
{
private static String serializeDocument(Document doc)
{
String xml = null;
try
{
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
Properties outFormat = new Properties();
outFormat.setProperty(OutputKeys.INDENT, "yes");
outFormat.setProperty(OutputKeys.METHOD, "xml");
outFormat.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
outFormat.setProperty(OutputKeys.VERSION, "1.0");
outFormat.setProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperties(outFormat);
DOMSource domSource = new DOMSource(doc.getDocumentElement());
OutputStream output = new StringOutputStream();
StreamResult result = new StreamResult(output);
transformer.transform(domSource, result);
xml = output.toString();
android.util.Log.i("XMLHELPER", xml);
}
catch (TransformerConfigurationException e)
{
android.util.Log.d("XMLHELPER", "Exception: " + e);
e.printStackTrace();
}
catch (TransformerException e)
{
android.util.Log.d("XMLHELPER", "Exception: " + e);
e.printStackTrace();
}
return xml;
}
}
下面是API第4級的解決方案它需要外部庫,但庫不是很大,使這是一個容易得多。
我用XOM 1.2.6及其核心包只有jar文件。
全部活動代碼包括進口:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import nu.xom.converters.DOMConverter;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class XOMTestActivity extends Activity {
private static final String TAG = "XOMTestActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//Used XOM project.xml file for testing
InputStream rawStream = this.getResources().openRawResource(R.raw.project);
Document document = docBuilder.parse(rawStream);
//API Level 4 will not always return a valid Document for XOM
//So, find the root level element manually
NodeList nodeList = document.getChildNodes();
Node elementNode = null;
for(int i = 0 ; i < nodeList.getLength() ; i++) {
Node n = nodeList.item(i);
if(n instanceof Element) {
elementNode = n;
break;
}
}
//assuming there was a root level element
DocumentFragment docFragment = document.createDocumentFragment();
docFragment.appendChild(elementNode);
nu.xom.Nodes nodes = DOMConverter.convert(docFragment);
nu.xom.Document xomDoc = new nu.xom.Document((nu.xom.Element) nodes.get(0));
Log.d(TAG, "onCreate: " + xomDoc.toXML());
String outFile =
Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "wc3-xom-doc.xml";
Writer writer = new FileWriter(outFile);
writer.write(xomDoc.toXML());
writer.close();
} catch(DOMException de) {
Log.e(TAG, "onCreate: dom exception: " + de.code, de);
} catch(Exception e) {
Log.e(TAG, "onCreate: exception", e);
}
}
}
這不是非常長。由於您可以跳過查找根元素所需的所有工作,因此對於API級別7+而言,它會稍微短一些。結果apk是162k,所以我不覺得XOM增加了一個項目的重量。
神奇的是在。
將xml文檔寫入文件,就像在SD卡上一樣? – 2010-02-18 18:08:04
其實哪裏都沒關係。序列化DOM到一個字符串是我想要做的。 – 2010-02-18 19:25:25
我推薦http://jsoup.org,這對於處理xml來說絕不簡單。特別是,它避免了使用中的'NullPointerException'。 – 2012-02-27 05:42:22