Java добавляет документы XML в существующие документы
У меня есть два документа XML, которые я создал, и я хочу объединить эти два внутри нового конверта. Итак, я
<alert-set>
<warning>National Weather Service...</warning>
<start-date>5/19/2009</start-date>
<end-date>5/19/2009</end-date>
</alert-set>
и
<weather-set>
<chance-of-rain type="percent">31</chance-of-rain>
<conditions>Partly Cloudy</conditions>
<temperature type="Fahrenheit">78</temperature>
</weather-set>
Что я хотел бы сделать, это объединить два в корневом каталоге node: <DataSet> комбинированные документы </Набор данных >
Я попытался создать временный документ и заменить дочерние узлы корневыми узлами документов:
<DataSet>
<blank/>
<blank/>
</DataSet>
И я надеялся заменить два пробела корневыми элементами двух документов, но я получил "WRONG_DOCUMENT_ERR: A node используется в другом документе, чем тот, который его создал". Я попытался принять и импортировать корневые узлы, но получаю ту же ошибку.
Нет ли простого способа комбинирования документов без необходимости чтения и создания новых элементов для каждого node?
EDIT: примеры фрагментов кода
Просто попробуйте переместить его в "пустой" документ на данный момент... Функции importNode и acceptNode не могут импортировать/принимать узлы Document, но они не могут импортировать элемент node и его поддерево... или если это так, он, похоже, не работает для добавления/замены.
Document xmlDoc; //created elsewhere
Document weather = getWeather(latitude, longitude);
Element weatherRoot = weather.getDocumentElement();
Node root = xmlDoc.getDocumentElement();
Node adopt = weather.adoptNode(weatherRoot);
Node imported = weather.importNode(weatherRoot, true);
Node child = root.getFirstChild();
root.replaceChild(adopt, child); //initially tried replacing the <blank/> elements
root.replaceChild(imported, child);
root.appendChild(adopt);
root.appendChild(imported);
root.appendChild(adopt.cloneNode(true));
Все они вызывают DOMException: WRONG_DOCUMENT_ERR: A node используется в другом документе, чем тот, который его создал.
Я думаю, мне нужно выяснить, как использовать stax или просто перечитать документы и создать новые элементы... Это похоже на работу слишком много, чтобы объединять документы.
Ответы
Ответ 1
Это немного сложно, но выполняется следующий пример:
public static void main(String[] args) {
DocumentImpl doc1 = new DocumentImpl();
Element root1 = doc1.createElement("root1");
Element node1 = doc1.createElement("node1");
doc1.appendChild(root1);
root1.appendChild(node1);
DocumentImpl doc2 = new DocumentImpl();
Element root2 = doc2.createElement("root2");
Element node2 = doc2.createElement("node2");
doc2.appendChild(root2);
root2.appendChild(node2);
DocumentImpl doc3 = new DocumentImpl();
Element root3 = doc3.createElement("root3");
doc3.appendChild(root3);
// root3.appendChild(root1); // Doesn't work -> DOMException
root3.appendChild(doc3.importNode(root1, true));
// root3.appendChild(root2); // Doesn't work -> DOMException
root3.appendChild(doc3.importNode(root2, true));
}
Ответ 2
Я знаю, что проблема решена уже, но я все еще хотел взять удар по этой проблеме, используя библиотеку XOM, которая Я сейчас тестирую (связанный с этот вопрос), и при этом предлагаю другой подход, отличный от ответа Andreas_D.
(Чтобы упростить этот пример, я помещаю ваши <alert-set>
и <weather-set>
в отдельные файлы, которые я прочитал в nu.xom.Document
экземпляры.)
import nu.xom.*;
[...]
Builder builder = new Builder();
Document alertDoc = builder.build(new File("src/xomtest", "alertset.xml"));
Document weatherDoc = builder.build(new File("src/xomtest", "weatherset.xml"));
Document mainDoc = builder.build("<DataSet><blank/><blank/></DataSet>", "");
Element root = mainDoc.getRootElement();
root.replaceChild(
root.getFirstChildElement("blank"), alertDoc.getRootElement().copy());
root.replaceChild(
root.getFirstChildElement("blank"), weatherDoc.getRootElement().copy());
Ключ должен сделать копию элементов, которые нужно вставить в mainDoc
; в противном случае вы получите жалобу, что "у ребенка уже есть родитель".
Вывод mainDoc теперь дает:
<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
<alert-set>
<warning>National Weather Service...</warning>
<start-date>5/19/2009</start-date>
<end-date>5/19/2009</end-date>
</alert-set>
<weather-set>
<chance-of-rain type="percent">31</chance-of-rain>
<conditions>Partly Cloudy</conditions>
<temperature type="Fahrenheit">78</temperature>
</weather-set>
</DataSet>
К моему удовольствию, это оказалось очень прямолинейным для XOM. Потребовалось всего несколько минут, чтобы написать это, хотя я определенно не очень разбираюсь в библиотеке. (Это было бы еще проще без элементов <blank/>
, т.е. Начиная с простого <DataSet></DataSet>
.)
Итак, если у вас нет веских причин использовать только стандартные инструменты JDK, я настоятельно рекомендую попробовать XOM, так как это может сделать обработку XML на Java намного приятнее.