0

I've edited the text attribute of an EditText node, and I'd now like to commit it to the DOM and I don't know how. This is what I have so far:

InputStream fXmlFile = resources.openRawResource(R.raw.pages);

            //Reads xml file and gets the node types and attributes
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);
            doc.getDocumentElement().normalize();
            NodeList nList = doc.getElementsByTagName("*");
            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp);   
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) nNode;
                    if(eElement.getNodeName().compareTo("EditText")==0)
                    {
                        String resName = eElement.getAttribute(ANDROID_ID);
                        resName = resName.replace("@+id/", "");
                        System.out.println(eElement.getNodeName()+" " + eElement.getAttribute(ANDROID_ID));
                        int resID = resources.getIdentifier(resName, "id", "mfc.generalgui2");
                        //get value from edittext field
                        String value = ((EditText) findViewById(resID)).getText().toString();
                        //set text attribute to value
                        eElement.setAttribute("android:text", value);
                    }
                }
            }
        } 
        catch (Exception e) {
            System.out.println("Catch");
            e.printStackTrace();
        }   

Converting DOM to String code:

TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");


            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(doc);
            trans.transform(source, result);
            String xmlString = sw.toString();
            System.out.println(xmlString);
litterbugkid
  • 3,534
  • 7
  • 36
  • 54
  • Maybe this could help http://stackoverflow.com/questions/2290945/writing-xml-on-android – user994886 Nov 26 '11 at 17:02
  • setAttribute call is a mutating call. What is the error that you are seeing? – Pavan Nov 26 '11 at 17:05
  • @PavanSudarshan There is no error. I want to mutate the attribute, and then commit it to the original DOM. – litterbugkid Nov 26 '11 at 17:09
  • Then setAttribute should do that for you, since you are not creating any new elements on which you are doing this. Am I missing something? – Pavan Nov 26 '11 at 17:13
  • @PavanSudarshan I'm not creating any new elements, I am editing them. Is it changed in the original DOM then? Or would I need to replace the old element with the new element? – litterbugkid Nov 26 '11 at 17:18
  • 1
    What do you mean by "commit it to original DOM"? setAttribute() modifies the original DOM so what else are you trying to get? If you want to save changes to the installed application, then you can't do that in the general case. If you want to output the result somewhere else, then you can use javax.xml.transform.Transformer for identity transformation. – praetorian droid Nov 26 '11 at 17:31
  • @praetoriandroid When I say "commit it to original DOM" I mean for example x+1 doesnt +1 to x permanently does it? You have to assign it back to x, like x = x+1. So using that same thinking I thought maybe yes I've changed the node attribute, but do I then need to replace the old node with the new node in the DOM so it's actually edited it. Another thing I want to do is to convert a Document to a String. I've seen a couple stackoverflow threads but can't work out how to do it.. Transformer isnt available for Android 2.1. – litterbugkid Nov 26 '11 at 20:36
  • @praetoriandroid If you put your comment into a proper answer I can accept it for you and give you the rep. – litterbugkid Feb 25 '12 at 08:53

1 Answers1

0

I forget the link to the documentation. But if I remember right, you can not make changes to the resource - as the code you use R.raw.pages.

To save a DOM tree to a file, you can use this code:

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import java.io.File;
import java.io.FileOutputStream;

...

//your document
Document doc = dBuilder.parse(fXmlFile);

OutputFormat format = new OutputFormat(doc);
format.setIndenting(true);

FileOutputStream fos = new FileOutputStream(new File("your-file"));
try {
  XMLSerializer serializer = new XMLSerializer(fos, format);
  serializer.serialize(doc);
} finally {
  fos.close();
}

I'm using Apache XML.

  • Do you know if this is compatible with Android 2.1? Do you know how to save to a String instead of a file? – litterbugkid Nov 27 '11 at 00:32
  • Apache XML is a library, you can use it in Android. And to write DOM tree to a string, you can serialize it to `StringWriter`: `java.io.StringWriter sw = new java.io.StringWriter(); XMLSerializer serializer = new XMLSerializer(sw, format);`. And then to get the string: `sw.toString()`. –  Nov 28 '11 at 00:19
  • Eclipse isn't recognising OutputFormat, nor the imports, I'm going to have to download the library and add it to my application project I think. – litterbugkid Nov 28 '11 at 14:29
  • I am very sorry, the library I used is Apache Xerces, you can download it here: http://xerces.apache.org/xerces2-j/ . I'm sorry again... –  Nov 29 '11 at 00:43
  • Do you know which one I need to download and there to put it? And in what format? http://xerces.apache.org/mirrors.cgi – litterbugkid Nov 29 '11 at 09:56
  • At section _Binary Distributions_, sub section _Xerces2 Java_, you can download one of the mirrors. After that extract all files into a directory, then add _xercesImpl.jar_ to your project. `OutputFormat` and `XMLSerializer` are located at `com.sun.org.apache.xml.serialize.*` –  Nov 30 '11 at 06:28
  • I've managed to import the .jar, and eclipse seems to recognise the imports, but the names are crossed out? Is it to do with them being deprecated? – litterbugkid Dec 01 '11 at 00:16
  • Hi, I am sorry again. All of my above direction was in my memory. This time I really code and compile, then run it. You need to add _xml-apis.jar_ to your project. About deprecated imports, I have no idea. I am using that `OutputFormat` and `XMLSerializer` in my projects :-) –  Dec 01 '11 at 18:53
  • Is xml-apis.jar available from that same website? – litterbugkid Dec 01 '11 at 21:37
  • Yes, it is included in the download file that I mentioned. I'm sorry, these days I need time for outside work so I have been answering you lately. –  Dec 02 '11 at 07:51
  • I edited my first post with my code I'm using to convert to String. The methods you used are not available in xml-apis.jar so I'm using Transformers. I'm getting the following error though: "[2011-12-02 11:31:44 - GeneralGUI7] Dx trouble processing "javax/xml/XMLConstants.class": Ill-advised or mistaken usage of a core class (java.* or javax.*) when not building a core library." – litterbugkid Dec 02 '11 at 11:38
  • Yes, the methods I used are located in _xercesImpl.jar_, and _xml-apis.jar_ is just for references of some classes that _xercesImpl.jar_ uses. The last time I really code and compile, run the test successfully. I am sorry I could not help you out of this :-( And sorry for my late reply... –  Dec 06 '11 at 01:55
  • Hi, I've moved to jsoup, have a look at jsoup.org. It is easier to handle your xml. Life's changing :-) –  Jan 29 '12 at 02:47