Java 向根元素添加元素

Java 向根元素添加元素,java,xml,jdom,Java,Xml,Jdom,我有一个类似这样的XML文件(一个mavenpom.XML,如果大家熟悉的话): 4.0.0 ... 我想添加一个元素,使其看起来像这样 4.0.0 聚甲醛 所以我这样做了: doc = (Document)builder.build(modelToWriteTo); rootProj = doc.getRootElement(); Element packagingTag = rootProj.getChild("packaging"); if(packagingTag != null

我有一个类似这样的XML文件(一个maven
pom.XML
,如果大家熟悉的话):


4.0.0
...
我想添加一个
元素,使其看起来像这样


4.0.0
聚甲醛
所以我这样做了:

doc = (Document)builder.build(modelToWriteTo);
rootProj = doc.getRootElement();
Element packagingTag = rootProj.getChild("packaging");
if(packagingTag != null) {
        packagingTag.setText(elementValue);         
} else {
    packagingTag = new Element("packaging").setText(elementValue);
    rootProj.addContent(packagingTag);  
}
因此,如果有一个名为“packaging”的子元素,那么我只想重置该值,如果没有,那么我想添加一个新标记

问题是当我这样做时,我的
元素如下所示:


聚甲醛
所以我在某个地方读到它可能与名称空间有关,所以我将代码改为:

doc = (Document)builder.build(modelToWriteTo);
rootProj = doc.getRootElement();
Element packagingTag = rootProj.getChild("packaging");
if(packagingTag != null){
        packagingTag.setText(elementValue);         
} else {
    packagingTag = new Element("packaging").setText(elementValue);
    packagingTag.setNamespace(rootProj.getNamespace());
    rootProj.addContent(packagingTag);      
}
而且它在没有
xmlns
属性的情况下显示得很好:


聚甲醛
但是,当另一个线程进来再次读取它,并找到
rootProj.getChild(“打包”)
时,它返回
null
。 因此,另一次修改打包标签的尝试会导致线程认为它不存在,并添加一个新标签,从而导致:


聚甲醛
聚甲醛
聚甲醛
在前面的代码中,我没有设置名称空间,它能够检索
rootProj.getChild(“打包”)


我一定错过了什么,但我看不到在哪里。请帮忙

您需要使用该方法的版本并传递正确的名称空间(在本例中为
http://maven.apache.org/POM/4.0.0

您请求的是不在名称空间中的
packaging
元素,但不存在这样的节点,因为您的
packaging
节点位于默认名称空间(
xmlns=)http://maven.apache.org/POM/4.0.0“
)。选择元素时需要指定此命名空间:

Element packagingTag = rootProj.getChild("packaging", 
    Namespace.getNamespace("http://maven.apache.org/POM/4.0.0"));
注意:它以前工作的原因是:

<packaging xmlns="">pom</packaging>
pom

…包含一个名称空间“取消声明”(
xmlns=”“
),该名称空间将元素还原为不存在于任何名称空间中。

如果不知道您使用的是哪种XML API,则很难回答此问题。每个标记使用jdom,但同意它应该是最前面和最中间的:使用jdom…所以每次我想要孩子的时候似乎都是这样,我必须声明一个名称空间。这很麻烦,但很有效。我没有使用Namespace.getNamespace(..),而是使用了rootProj.getChild(“packaging”,rootProj.getNamespace())。。Thanks@ALQH-是的,元素是否在命名空间中很重要。从根本上说,如果不指定节点所在的名称空间,就不是在请求正确的节点。