2010-02-18 9 views
35

org.w3c.dom.Document के उदाहरण को देखते हुए, मैं अपनी सामग्री को फ़ाइल/स्ट्रीम में कैसे सहेजूं?एंड्रॉइड पर XML लिखना

संपादित करें: जैसा कि कॉमन्सवेयर ने बताया, एंड्रॉइड 2.2 (एपीआई 8) से पहले एंड्रॉइड एसडीके से कक्षाओं का उपयोग करके ऐसी कोई संभावना नहीं है। क्या आप Document सामग्री को फ़ाइल/स्ट्रीम में सहेजने के लिए किसी तृतीय-पक्ष लाइब्रेरी की अनुशंसा कर सकते हैं?

+0

एसडी कार्ड की तरह xml दस्तावेज़ को फ़ाइल में लिखना? –

+0

असल में इससे कोई फर्क नहीं पड़ता कि कहां है। एक स्ट्रिंग में डीओएम को सीरियलाइज करना वह है जो मैं करना चाहता हूं। –

+1

मैं http://jsoup.org की अनुशंसा करता हूं, यह xml को संभालने के लिए कभी भी आसान नहीं है। विशेष रूप से, यह उपयोग में 'NullPointerException' से बचाता है। –

उत्तर

39

आप अन्य सभी टेक्स्ट फ़ाइलों की तरह 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); 
    } 
} 
+2

इस उत्तर के लिए धन्यवाद। मुझे पता है कि मैं अपने आप से दस्तावेज़ को पार कर सकता हूं लेकिन मैं ऐसा नहीं करता। आपके द्वारा पोस्ट किया गया कोड उत्पादन-तैयार/भरोसेमंद नहीं दिखता है:/ –

+8

यह कोड उदाहरण है और उत्पादन के लिए नहीं है :) – Dmytro

+0

getStringFromNode() फ़ंक्शन मूल XML सामग्री (जटिल XML के लिए परीक्षण नहीं) के लिए पूरी तरह से काम करता है, बहुत बहुत धन्यवाद। यह एंड्रॉइड संस्करणों के लिए बहुत मदद करता है <2.2 जब ट्रांसफॉर्मर फैक्ट्री का उपयोग नहीं किया जा सकता है। –

20

पढ़ने के लिए एक बहुत हल्के ढांचे और एनोटेट जावा से एक्सएमएल लिख नहीं है वस्तुओं। यह एंड्रॉइड के साथ पूरी तरह से संगत है।

http://simple.sourceforge.net

+1

मैंने इस ढांचे की कोशिश की और यह एंड्रॉइड पर शानदार है। यह प्रतिबिंब का उपयोग करता है लेकिन यह शायद अधिकांश मामलों के लिए एक मुद्दा नहीं होगा। – Qberticus

+2

यह प्रतिबिंब का उपयोग करता है, हालांकि प्रतिबिंब एनोटेटेड कक्षाओं के आधार पर एक्सएमएल स्कीमा को स्कैन करने के लिए केवल एक बार किया जाता है। प्रदर्शन में सुधार के लिए सभी प्रतिबिंब कैश किए गए हैं। यह जेएक्सबी और एक्सस्ट्रीम जैसे समान ढांचे की तुलना में तेज़ है, और कई परिदृश्यों पर देशी जावा एक्सएमएल क्रमिकरण से भी तेज है। –

+0

बहुत बढ़िया lib, मैं अब इसका उपयोग करता हूं। मैं इसे ORMLite के संयोजन के साथ वास्तव में उपयोग करता हूं, और साथ में मेरे पास कुछ ही कक्षाएं हैं, इन सभी libs के साथ सभी एनोटेटेड हैं, और मैं एक्सएमएल से deserialize कर सकते हैं और कोड की कुछ पंक्तियों के साथ SQLite में सहेज सकते हैं। बहुत बढ़िया :) – Adam

16

एपीआई स्तर 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); 
+0

मेरा ऐप एपीआई स्तर 4 को लक्षित करता है –

7

मुझे पता इसहाक एपीआई स्तर 4 का उपयोग कर एक समाधान के लिए देख रहा था, लेकिन दूसरों के लिए एक न्यूनतम स्तर 8 उपयोग कर सकते हैं, जो यहाँ है एक अच्छा समाधान क्या के आधार पर राडेक-कश्मीर पोस्ट:

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; 
    } 
} 
10

यहाँ एपीआई स्तर 4. के लिए एक समाधान है यह जरूरी है एक बाहरी पुस्तकालय, तथापि, पुस्तकालय नहीं बड़ी है और यह एक बहुत आसान बना देता है।

मैंने XOM 1.2.6 और इसके मूल पैकेज केवल जार फ़ाइल का उपयोग किया। आयात सहित

पूर्ण गतिविधि कोड:

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); 
     } 

    } 
} 

यह बहुत लंबे समय तक नहीं है। एपीआई स्तर 7+ के लिए यह काफी छोटा होगा क्योंकि आप मूल तत्व को खोजने के लिए आवश्यक सभी कार्यों को छोड़ सकते हैं। परिणाम एपीके 162k है इसलिए मुझे नहीं लगता कि एक्सओएम एक परियोजना में बहुत अधिक वजन जोड़ता है।

जादू DOMConverter में है।

संबंधित मुद्दे