Добавление элемента в корневой элемент - PullRequest
1 голос
/ 29 декабря 2011

У меня есть XML-файл, который выглядит примерно так (maven pom.xml, если кто-нибудь знает):

<?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>

Я хотел добавить добавить элемент <packaging>, чтобы он выглядел следующим образом

<?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>

Итак, я сделал это:

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> появился так:

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

Так что я где-то читал, что это может быть связано с пространством имен, поэтому я изменилмой код:

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:

<project>
    <packaging>pom</packaging>
</project>

Однако , когда другой поток приходит, чтобы прочитать его сноваи найти rootProj.getChild("packaging"), он возвращает null.таким образом, другая попытка изменить тег упаковки приводит к тому, что поток думает, что он не существует, и добавляет новый тег, в результате чего:

<project>
    <packaging>pom</packaging>
    <packaging>pom</packaging>
    <packaging>pom</packaging>
</project>

с предыдущим кодом, в котором я не устанавливал пространство имен,он смог получить rootProj.getChild("packaging") .....

Я, должно быть, что-то здесь упустил, но я не могу видеть, где.Пожалуйста, помогите!

Ответы [ 2 ]

1 голос
/ 29 декабря 2011

Вы запрашиваете элемент 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>

... содержитпространство имен "undeclaration" (xmlns=""), которое возвращает элемент к существующему без пространства имен.

1 голос
/ 29 декабря 2011

Вам необходимо использовать версию метода Element.getChild(String, Namespace) и передать правильное пространство имен (которое в данном случае равно http://maven.apache.org/POM/4.0.0).

...