无法通过 Java 代码从 XML 文档中删除元素和子元素
Can't remove element and child element from an XML document by Java code
这是我的 xml 文档:
<definitions>
<task name="TASK1"
class="CLASS"
group="GROUP">
<trigger count="3" interval="400"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE1"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE2"/>
</task>
<task name="TASK1"
class="CLASS"
group="GROUP">
<trigger count="1" interval="600"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE1"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE2"/>
</task>
<another_tag name="a_name"/>
<another_tag2 name="a_name2"/>
<another_tag3> something in the middle </another_tag3>
</definitions>
我必须删除所有 <task>
标签及其中的内容。我使用了这个 java 代码:
Document esb = new Document();
SAXBuilder saxBuilder = new SAXBuilder();
try {
esb = saxBuilder.build(new File("C:\...path\file.xml"));
}
catch (JDOMException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
Element root = esb.getRootElement();
boolean b = root.removeChild("task");
System.out.println(b);
我无法理解如何获取不带 <task>
标签且仅包含 <another_tag>
标签的 xml 文件。我一直在寻找其他解决方案,但没有任何用处。我也使用了 removeContent() 方法,但没有。我导入了 jdom2 库,我需要使用最近的库,因为 jdom 和 jdom2 之间的交互不好,所以我宁愿只使用最近的库。关于如何从此 xml CODE 中删除某些元素的任何建议?
api 函数 'removeChild' 是这样说的:
...这将删除具有给定本地名称且不属于任何名称空间的第一个 child 元素(深度一层)...
removeChild 函数只删除一个 child。因此,如果您想删除所有具有特定名称的 child,您需要使用循环。如果函数调用找不到具有所需名称的节点,它 returns 为 false.
如果我使用您的示例 xml 第三次调用 removeChild returns 为 false。所以下面的代码会删除所有任务 childs
...
boolean b = root.removeChild("task");
while (b)
b = root.removeChild("task");
...
除了 OkieOth 所说的,您只是删除了第一个任务。
另一个问题是您没有将 JDOM 再次写入文件。您需要保存现有文件才能看到更改。
如果您想将更改应用回文件,请考虑:
SAXBuilder saxBuilder = new SAXBuilder();
try {
Document esb = saxBuilder.build(new File("C:\...path\file.xml"));
Element root = esb.getRootElement();
boolean b = root.removeChild("task");
System.out.println(b);
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
try (OutputStream os = new FileOutputStream("C:\...path\file.xml")) {
xout.output(os, esb)
}
}
catch (JDOMException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
我通过管理命名空间解决了这个问题。有代码:`
Document doc = new Document();
SAXBuilder saxBuilder = new SAXBuilder();
try {
doc = saxBuilder.build(new File("....path\MyXMLfile.xml"));
}
catch (JDOMException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
Element root = esb.getRootElement();
System.out.println(root.getName()); // it prints "definitions"
Namespace namespace = Namespace.getNamespace("task","http://....myDefinitionsNamespace....");
boolean b = root.removeChildren("task", namespace);
System.out.println(b);
XMLOutputter xmlOutputter = new XMLOutputter();
xmlOutputter.setFormat(Format.getPrettyFormat());
System.out.println(xmlOutputter.outputString(doc)); //so we can see new XML FILE
为了理解这段代码,我们也需要开始xml:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://....myDefinitionsNamespace....">
<task name="MyTask"
class="....myClass...."
group="....myGroup....">
<taskChild/>
</task>
<anotherTag1/>
<anotherTag2>
<task/>
.
.
.
</definitions>
结果是一个没有每个任务标签的 XML 文件,它将只包含 anotherTags。然后您需要定义输出(例如输出到带有 FileOutputStream 实例的文件中)。
感谢@OkieOth 和@rolfl。
这是要使用的代码XPath to remove all task nodes incrementally using vtd-xml
import com.ximpleware.*;
import java.io.*;
public class removeElement {
public static void main(String s[]) throws VTDException,IOException{
VTDGen vg = new VTDGen();
if (!vg.parseFile("input.xml", false))
return;
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/definition/task");
XMLModifier xm = new XMLModifier(vn);
int i=0;
while((i=ap.evalXPath())!=-1){
xm.remove();
}
xm.output("output.xml");
}
}
这是我的 xml 文档:
<definitions>
<task name="TASK1"
class="CLASS"
group="GROUP">
<trigger count="3" interval="400"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE1"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE2"/>
</task>
<task name="TASK1"
class="CLASS"
group="GROUP">
<trigger count="1" interval="600"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE1"/>
<property xmlns:task="URI"
name="PROPERTY2"
value="VALUE2"/>
</task>
<another_tag name="a_name"/>
<another_tag2 name="a_name2"/>
<another_tag3> something in the middle </another_tag3>
</definitions>
我必须删除所有 <task>
标签及其中的内容。我使用了这个 java 代码:
Document esb = new Document();
SAXBuilder saxBuilder = new SAXBuilder();
try {
esb = saxBuilder.build(new File("C:\...path\file.xml"));
}
catch (JDOMException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
Element root = esb.getRootElement();
boolean b = root.removeChild("task");
System.out.println(b);
我无法理解如何获取不带 <task>
标签且仅包含 <another_tag>
标签的 xml 文件。我一直在寻找其他解决方案,但没有任何用处。我也使用了 removeContent() 方法,但没有。我导入了 jdom2 库,我需要使用最近的库,因为 jdom 和 jdom2 之间的交互不好,所以我宁愿只使用最近的库。关于如何从此 xml CODE 中删除某些元素的任何建议?
api 函数 'removeChild' 是这样说的: ...这将删除具有给定本地名称且不属于任何名称空间的第一个 child 元素(深度一层)...
removeChild 函数只删除一个 child。因此,如果您想删除所有具有特定名称的 child,您需要使用循环。如果函数调用找不到具有所需名称的节点,它 returns 为 false.
如果我使用您的示例 xml 第三次调用 removeChild returns 为 false。所以下面的代码会删除所有任务 childs
...
boolean b = root.removeChild("task");
while (b)
b = root.removeChild("task");
...
除了 OkieOth 所说的,您只是删除了第一个任务。
另一个问题是您没有将 JDOM 再次写入文件。您需要保存现有文件才能看到更改。
如果您想将更改应用回文件,请考虑:
SAXBuilder saxBuilder = new SAXBuilder();
try {
Document esb = saxBuilder.build(new File("C:\...path\file.xml"));
Element root = esb.getRootElement();
boolean b = root.removeChild("task");
System.out.println(b);
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
try (OutputStream os = new FileOutputStream("C:\...path\file.xml")) {
xout.output(os, esb)
}
}
catch (JDOMException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
我通过管理命名空间解决了这个问题。有代码:`
Document doc = new Document();
SAXBuilder saxBuilder = new SAXBuilder();
try {
doc = saxBuilder.build(new File("....path\MyXMLfile.xml"));
}
catch (JDOMException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
Element root = esb.getRootElement();
System.out.println(root.getName()); // it prints "definitions"
Namespace namespace = Namespace.getNamespace("task","http://....myDefinitionsNamespace....");
boolean b = root.removeChildren("task", namespace);
System.out.println(b);
XMLOutputter xmlOutputter = new XMLOutputter();
xmlOutputter.setFormat(Format.getPrettyFormat());
System.out.println(xmlOutputter.outputString(doc)); //so we can see new XML FILE
为了理解这段代码,我们也需要开始xml:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://....myDefinitionsNamespace....">
<task name="MyTask"
class="....myClass...."
group="....myGroup....">
<taskChild/>
</task>
<anotherTag1/>
<anotherTag2>
<task/>
.
.
.
</definitions>
结果是一个没有每个任务标签的 XML 文件,它将只包含 anotherTags。然后您需要定义输出(例如输出到带有 FileOutputStream 实例的文件中)。 感谢@OkieOth 和@rolfl。
这是要使用的代码XPath to remove all task nodes incrementally using vtd-xml
import com.ximpleware.*;
import java.io.*;
public class removeElement {
public static void main(String s[]) throws VTDException,IOException{
VTDGen vg = new VTDGen();
if (!vg.parseFile("input.xml", false))
return;
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/definition/task");
XMLModifier xm = new XMLModifier(vn);
int i=0;
while((i=ap.evalXPath())!=-1){
xm.remove();
}
xm.output("output.xml");
}
}