如何使用 JAVA 删除 XML 中的节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25001921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove a node in XML using JAVA
提问by diCoder
The XML file I use is like this, pay attention that there are 4 'target' tag.
我使用的 XML 文件是这样的,注意有 4 个 'target' 标签。
<?xml version="1.0" encoding="UTF-8" standalone="no"?><project basedir="." default="end" name="precompile">
<property name="charset" value="utf-8"/>
<target name="start">
</target>
<target depends="precompile-templates1,precompile-templates2" name="end">
<echo>finish generating precompiled templates</echo>
</target>
<target name="precompile-templates1">
<property name="outputJS1" value="jsp/jsp_2/js/templates.js"/>
<property name="templatesPath1" value="jsp/jsp_2/js/tmpl"/>
<java dir="${basedir}" failonerror="true" fork="true" jar="lib/js.jar">
<arg value="otherFiles/lib/rhino-handlebars-compiler.js"/>
<arg value="--handlebars"/>
<arg value="otherFiles/third-party/handlebars-v1.3.0.js"/>
<arg value="--templates"/>
<arg value="${templatesPath1}"/>
<arg value="--output"/>
<arg value="${outputJS1}"/>
</java>
<echo>Template Precompiled to web/js/compiled-templates.js</echo>
<echo> is now ready to compress....</echo>
</target>
<target name="precompile-templates2">
<property name="outputJS2" value="jsp/jsp_3/js/templates.js"/>
<property name="templatesPath2" value="jsp/jsp_3/js/tmpl"/>
<java dir="${basedir}" failonerror="true" fork="true" jar="lib/js.jar">
<arg value="otherFiles/lib/rhino-handlebars-compiler.js"/>
<arg value="--handlebars"/>
<arg value="otherFiles/third-party/handlebars-v1.3.0.js"/>
<arg value="--templates"/>
<arg value="${templatesPath2}"/>
<arg value="--output"/>
<arg value="${outputJS2}"/>
</java>
<echo>Template Precompiled to web/js/compiled-templates.js</echo>
<echo> is now ready to compress....</echo>
</target></project>
I want to keep the first 2 'target' node but remove the rest 2 nodes of 'target'. What should I do? I was trying to do something like this:
我想保留前 2 个“目标”节点,但删除“目标”的其余 2 个节点。我该怎么办?我试图做这样的事情:
File fXmlFile = new File(subBuildFile);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
Node s = doc.getElementsByTagName("target").item(1);
for(int i =2; i<doc.getElementsByTagName("target").getLength();i++){
doc.getElementsByTagName("target").item(i).removeChild(doc.getElementsByTagName("target").item(i));
}
But there always is a similar error like this:
但是总是有类似这样的错误:
Exception in thread "main" org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist.
at com.sun.org.apache.xerces.internal.dom.ParentNode.internalRemoveChild(Unknown Source)
at com.sun.org.apache.xerces.internal.dom.ParentNode.removeChild(Unknown Source)
at xmlReader.Test.resetXML(Test.java:52)
at xmlReader.Test.main(Test.java:39)
Any suggestion?
有什么建议吗?
Plus: Something weird when I use the following codes:
另外:当我使用以下代码时有些奇怪:
System.out.println("the number of target tag is "+doc.getElementsByTagName("target").getLength());
for(int i =2; i<targets.getLength();i++){
root.removeChild(targets.item(2));
System.out.println(i);
}
System.out.println(doc.getElementsByTagName("target").getLength());
The XML I use is like this:
我使用的 XML 是这样的:
<target name="start">
</target>
<target depends="precompile-templates1,precompile-templates2" name="end">
<echo>finish generating precompiled templates</echo>
</target>
<target id="2">
</target>
<target id="3">
</target>
<target id="4">
</target>
<target id="5">
</target>
<target id="6">
</target>
<target id="7">
</target>
<target id="8">
</target>
<target id="9">
</target>
<target id="10">
</target>
<target id="11">
</target>
<target id="12">
</target>
<target id="13">
</target>
</project>
The output will like this:
输出将是这样的:
the number of target tag is 8
2
3
4
5
And the final output XML is like this:
而最终输出的 XML 是这样的:
<target name="start">
</target>
<target depends="precompile-templates1,precompile-templates2" name="end">
<echo>finish generating precompiled templates</echo>
</target>
<target id="11">
</target>
<target id="12">
</target>
<target id="13">
</target>
</project>
回答by laune
The expression
表达方式
doc.getElementsByTagName("target").item(i)
selects a <target>
and you can't remove a <target>
from it.
选择 a<target>
并且您不能从中删除 a <target>
。
Element root = doc.getDocumentElement(); // should be <project>
NodeList targets = doc.getElementsByTagName("target");
root.removeChild( targets.item( 3 ) );
root.removeChild( targets.item( 2 ) );
A more general code that's not hardwired on 2 would be:
在 2 上没有硬连线的更通用的代码是:
int toKeep = 2;
int toDelete = targets.getLength() - toKeep;
for(int i = 0; i < toDelete; i++){
root.removeChild(targets.item(toKeep));
}
Note that (in contrast to your code) the number of target elements to be deleted is computed up front. Limiting it with the changing length of the list create a strange effect.
请注意(与您的代码相反)要删除的目标元素的数量是预先计算的。通过改变列表长度来限制它会产生奇怪的效果。