我要如何插入一个新节点到现有的XML [英] How do I insert a new node to an existing 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屋!