在 Android 上编写 XML
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2290945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing XML on Android
提问by Marek Stój
Given an instance of org.w3c.dom.Document
, how do I save its contents to a file/stream?
给定 的实例org.w3c.dom.Document
,如何将其内容保存到文件/流?
EDIT:
As CommonsWare pointed out, there's no such possibility using classes from Android SDK prior to Android 2.2 (API 8). Can you recommend then a third-party library for saving Document
contents to a file/stream?
编辑:正如 CommonsWare 所指出的,在 Android 2.2 (API 8) 之前,使用来自 Android SDK 的类是不可能的。你能推荐一个第三方库来将Document
内容保存到文件/流吗?
回答by Dmytro
You can write xml like all others text files. For parsing Document to string I used:
您可以像所有其他文本文件一样编写 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();
}
But there is one more simple way to do this: http://www.ibm.com/developerworks/opensource/library/x-android/index.html#list11
但是还有一种更简单的方法可以做到这一点: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);
}
}
回答by ng.
There is a very lightweight framework for reading and writing XML from annotated Java objects. It is fully compatible with Android.
有一个非常轻量级的框架用于从带注释的 Java 对象读取和写入 XML。它与安卓系统完全兼容。
回答by plugmind
Since API level 8 you can use:
从 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);
回答by Rich Schuler
Here's a solution for API Level 4. It requires an external library, however, the library is not large and makes this a lot easier.
这是 API 级别 4 的解决方案。它需要一个外部库,但是,该库并不大,这使它变得容易得多。
I used XOM 1.2.6and its core packages only jar file.
我使用了XOM 1.2.6及其核心包,只有 jar 文件。
Full activity code including imports:
包括进口在内的完整活动代码:
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);
}
}
}
It's not terribly long. It would be quite a bit shorter for API level 7+ since you can skip all the work required to find the root element. Resulting apk is 162k so I don't feel XOM adds much weight to a project.
它不是很长。对于 API 级别 7+,它会更短一些,因为您可以跳过查找根元素所需的所有工作。结果 apk 是 162k,所以我不觉得 XOM 给项目增加了太多的权重。
The magic is in DOMConverter
.
魔法在DOMConverter
。
回答by Adam
I realize Isaac was looking for a solution using API level 4, but for others who can use a minimum level 8, here is a nice solution based off of what radek-k posted:
我意识到 Isaac 正在寻找使用 API 级别 4 的解决方案,但对于可以使用最低级别 8 的其他人,这里有一个基于 radek-k 发布的内容的不错的解决方案:
StringOutputStream.java:
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:
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;
}
}