Reputation: 161
I have an XML file that looks something like this (a maven pom.xml
if anyone's familiar):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
...
</project>
I wanted to add add a <packaging>
element so that it looks like this
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
</project>
So I did this:
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);
}
so that if there's a child element called "packaging" then I just want to reset the value, if not then I want to add a new tag.
The problem is when I did that my <packaging>
element came as:
<project>
<packaging xmlns="">pom</packaging>
</project>
So I read somewhere it might be something to do with the namespace, so I changed my code to:
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);
}
and it appears nicely without the xmlns
attribute:
<project>
<packaging>pom</packaging>
</project>
However, when another thread comes in to read it again, and find rootProj.getChild("packaging")
, it returns null
.
thus, another attempt to modify the packaging tag lead to the thread thinking that it doesn't exist and adds a new tag resulting in:
<project>
<packaging>pom</packaging>
<packaging>pom</packaging>
<packaging>pom</packaging>
</project>
with the previous code where I didn't set the namespace, it was able to retrieve rootProj.getChild("packaging")
.....
I must have miss something here but I can't see where. Please help!
Upvotes: 1
Views: 334
Reputation: 60414
You're asking for the packaging
element that's in no namespace, but no such node exists, because your packaging
node is in the default namespace (xmlns="http://maven.apache.org/POM/4.0.0"
). You need to specify this namespace when selecting the element:
Element packagingTag = rootProj.getChild("packaging",
Namespace.getNamespace("http://maven.apache.org/POM/4.0.0"));
Note: The reason it worked before is because this:
<packaging xmlns="">pom</packaging>
...contains a namespace "undeclaration" (xmlns=""
) that reverts the element to existing in no namespace.
Upvotes: 1
Reputation: 12196
You need to use the Element.getChild(String, Namespace)
version of the method and pass the correct namespace (which in this case is http://maven.apache.org/POM/4.0.0
).
Upvotes: 1