无法通过Java代码从XML文档中删除元素和子元素

时间:2016-02-24 11:26:25

标签: java xml removechild jdom jdom-2

这是我的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代码中删除一些元素的任何建议?

4 个答案:

答案 0 :(得分:1)

api对函数'removeChild'说这个: ...这将删除具有给定本地名称且属于无名称空间的第一个子元素(一级深)

removeChild函数只删除一个子节点。因此,如果要删除具有特定名称的所有子项,则需要使用循环。如果函数调用找不到具有所需名称的节点,则返回false。

如果我使用您的示例x​​ml,则removeChild的第三次调用将返回false。因此,以下代码将删除所有任务子项

...
    boolean b = root.removeChild("task");
    while (b)
        b = root.removeChild("task");
...

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我通过管理命名空间解决了这个问题。有代码:`

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。

答案 3 :(得分:0)

以下是使用XPathvtd-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");

    }
}