我要如何插入一个新节点到现有的XML [英] How do I insert a new node to an existing XML

查看:144
本文介绍了我要如何插入一个新节点到现有的XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想插入一个新节点到一个存在的XML文件,但低于code再次将所有的节点。

I would like to insert a new node into a existent xml file, but The code below inserts all the nodes again.

我做一个测试,如果该文件存在。如果没有,我创建了一个新的XML文件,并写入标签。如果存在,它也创造了节点,但走错了路。

I do a test if the file exists. If not, I create a new xml file and write the tags. If exists, it also creates the nodes, but the wrong way.

//create a new file called "new.xml" in the SD card
File newxmlfile = new File(Environment.getExternalStorageDirectory() + "/download/teste/audit.xml");

if (newxmlfile.exists()){

    try{
        fileos = new FileOutputStream(newxmlfile, true);
    }catch(FileNotFoundException e){
        Log.e("FileNotFoundException", "can't create FileOutputStream");
    }


} else {                    

    try{
        newxmlfile.createNewFile();
    }catch(IOException e){
        Log.e("IOException", "exception in createNewFile() method");
    }

    try{
        fileos = new FileOutputStream(newxmlfile);
    }catch(FileNotFoundException e){
        Log.e("FileNotFoundException", "can't create FileOutputStream");
    }
}

//we create a XmlSerializer in order to write xml data
XmlSerializer serializer = Xml.newSerializer();
try {
    serializer.setOutput(fileos, "UTF-8");
    serializer.startDocument(null, Boolean.valueOf(true));
    serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

    serializer.startTag(null, "root");
        serializer.startTag(null, "child1");
        serializer.endTag(null, "child1");

        serializer.startTag(null, "child2");
        serializer.attribute(null, "attribute", "value");
        serializer.endTag(null, "child2");

            serializer.startTag(null, "child3");
        serializer.text("some text inside child3");
        serializer.endTag(null, "child3");                           
    serializer.endTag(null, "root");
    serializer.endDocument();
    serializer.flush();
    fileos.close();

    Context context = getApplicationContext();
    CharSequence text = "Save!";
    int duration = Toast.LENGTH_SHORT;
    Toast toast = Toast.makeText(context, text, duration);
    toast.show();

} catch (Exception e) {
    Log.e("Exception","error occurred while creating xml file");
}

结果是这样的:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<root>
  <child1 />
  <child2 attribute="value" />
  <child3>some text inside child3</child3>
</root><?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<root>
  <child1 />
  <child2 attribute="value" />
  <child3>some text inside child3</child3>
</root>

但我想要的结果是这样的:

But I want the result like this:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<root>
  <child1 />
  <child2 attribute="value" />
  <child3>some text inside child3</child3>
  <child1 />
  <child2 attribute="value" />
  <child3>some text inside child3</child3>
</root>

谢谢!

推荐答案

看起来像有没有在Android中这样的API。但是,您仍然有以下几种选择来解决这个问题:

Looks like there's not such API in Android. However, You still have the following options to fix the issue:


  • 寻找一些开源库,它提供了这样的能力;

  • 难道还在使用的XmlSerializer 一些手动的字符串操作,如提供如下:

  • Look for some open-source library which provides such ability;
  • Do some manual string operations still using XmlSerializer, like provided below:

private void testXMLFiles() {
    //create a new file called "new.xml" in the SD card
    final File newXmlFile = new File(Environment.getExternalStorageDirectory() + "/download/teste/audit.xml");
    RandomAccessFile randomAccessFile = null;
    final boolean fileExists = newXmlFile.exists();
    String lastLine = null;

    if (fileExists) {
        try {
            randomAccessFile = new RandomAccessFile(newXmlFile, "rw");
            randomAccessFile.seek(0);

            if (null != randomAccessFile) {
                final Scanner scanner = new Scanner(newXmlFile);
                int lastLineOffset = 0;
                int lastLineLength = 0;

                while (scanner.hasNextLine()) {
                    // +1 is for end line symbol
                    lastLine = scanner.nextLine();
                    lastLineLength = lastLine.length() + 2;
                    lastLineOffset += lastLineLength;
                }

                // don't need last </root> line offset
                lastLineOffset -= lastLineLength;

                // got to string before last
                randomAccessFile.seek(lastLineOffset);
            }
        } catch(FileNotFoundException e) {
            Log.e("FileNotFoundException", "can't create FileOutputStream");
        } catch (IOException e) {
            Log.e("IOException", "Failed to find last line");
        }
    } else {
        try {
            newXmlFile.createNewFile();
        } catch(IOException e) {
            Log.e("IOException", "exception in createNewFile() method");
        }

        try {
            randomAccessFile = new RandomAccessFile(newXmlFile, "rw");
        } catch(FileNotFoundException e) {
            Log.e("FileNotFoundException", "can't create FileOutputStream");
        }
    }

    //we create a XmlSerializer in order to write xml data
    XmlSerializer serializer = Xml.newSerializer();

    if (randomAccessFile == null) {
        return;
    }

    try {
        final StringWriter writer = new StringWriter();

        serializer.setOutput(writer);

        if (!fileExists) {
            serializer.startDocument(null, true);
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
            serializer.startTag(null, "root");
        } else {
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
        }

        serializer.startTag(null, "child1");
        serializer.endTag(null, "child1");

        serializer.startTag(null, "child2");
        serializer.attribute(null, "attribute", "value");
        serializer.endTag(null, "child2");

        serializer.startTag(null, "child3");
        serializer.text("some text inside child3");
        serializer.endTag(null, "child3");

        if (!fileExists) {
            serializer.endTag(null, "root");
        }

        serializer.flush();

        if (lastLine != null) {
            serializer.endDocument();
            writer.append(lastLine);
        }

        // Add \n just for better output in console
        randomAccessFile.writeBytes(writer.toString() + "\n");
        randomAccessFile.close();

        Toast.makeText(getApplicationContext(), "Save!", Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        Log.e("Exception","error occurred while creating xml file");
        e.printStackTrace();
    }
}


第二轮后的输出如下(非常类似于您期望的那样):

Its output after second run is the following (quite similar to what You expect):

<?xml version='1.0' standalone='yes' ?>
<root>
  <child1 />
  <child2 attribute="value" />
  <child3>some text inside child3</child3>

<child1 />
<child2 attribute="value" />
<child3>some text inside child3</child3></root>


  • 店铺从最初的XML所有标签(例如,使用的SAXParser 你可以读取标签,写入新文件的同时,用在最后apppend新的的XMLSerializer );

    • Store all tags from initial xml (e.g. using SAXParser you can read tags, write to new file the same time and apppend new ones at the end using XMLSerializer);
    • 这篇关于我要如何插入一个新节点到现有的XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆