1

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!

2
  • This question is difficult to answer without knowing which XML API you are using. Commented Dec 29, 2011 at 2:50
  • jdom per tag but agree that it should be up front and center: Using JDOM ... Commented Dec 29, 2011 at 3:01

2 Answers 2

1

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).

Sign up to request clarification or add additional context in comments.

Comments

1

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.

2 Comments

so it seems like everytime when I want to get a child, i have to state a namespace. troublesome, but it works. instead of going Namespace.getNamespace(..) , i just used rootProj.getChild("packaging", rootProj.getNamespace()) .. Thanks
@ALQH - Right, it's significant that an element is in a namespace or that it isn't. Fundamentally, you're not asking for the right node if you don't specify the namespace the node exists in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.