在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:17:24  来源:igfitidea点击:

Writing XML on Android

xmlandroidserialization

提问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 Documentcontents 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。它与安卓系统完全兼容。

http://simple.sourceforge.net

http://simple.sourceforge.net

回答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;
    }
}