Я использую функцию, которая принимает два элемента DOM - родительский и дочерний из разных документов. Я импортирую дочерний элемент, преобразую его, а затем присоединяю его к родительскому элементу. Но последняя строка в следующем коде бросает исключение dom: org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: Узел используется в другом документе, кроме того, который его создал.Преобразование и добавление Dom Node
Пожалуйста, смотрите мой код ниже:
public void attachNodeToParent (Element parent, Element child) throws Exception {
Document parent_doc = parent.getOwnerDocument();
child = (Element)parent_doc.importNode(child, true);
// Imported child Element is shown below:
// <node id="101">
// <node id="102">
// <node id="103" />
// </node>
// <node id="104">
// <node id="103" />
// </node>
// </node>
// convert child Element into String
Source source = new DOMSource(child);
StringWriter stringWriter = new StringWriter();
Result result = new StreamResult(stringWriter);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.transform(source, result);
String childXml = stringWriter.getBuffer().toString();
// Recursively modify the id attributes of every node
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(childXml)));
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
NodeList nodes = (NodeList) xpath.compile("//node[@id]").evaluate(doc, XPathConstants.NODESET);
for (int nodeNumber = 0; nodeNumber < nodes.getLength(); ++nodeNumber) {
final Element node = (Element) nodes.item(nodeNumber);
final String nodeId = node.getAttribute("id");
final String newNodeId = "prefix/" + nodeId;
node.getAttributeNode("id").setValue(newNodeId);
}
final StringWriter writer = new StringWriter();
transformer.transform(source, new StreamResult(writer));
writer.flush();
writer.close();
String transformedChildXml = writer.toString();
// Prase transformedChildXml String into XML
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(transformedChildXml)));
document.setXmlStandalone(false);
child = document.getDocumentElement();
// child Element is now transformed to:
// <node id="prefix/101">
// <node id="prefix/102">
// <node id="prefix/103" />
// </node>
// <node id="prefix/104">
// <node id="prefix/103" />
// </node>
// </node>
// append transformed child Element to parent Element
// Throws o rg.w3c.dom.DOMException: WRONG_DOCUMENT_ERR:
// A node is used in a different document than the one that created it.
parent.appendChild(child);
}
После импорта узла изначально я не уверен, как преобразовать идентификаторы рекурсивно. Если узел имеет несколько подуровней (2 под-уровня в моем примере), то я рекурсивно прохожу через каждый уровень? – sony
Да, вы можете пройти дерево DOM с рекурсией, или вы можете получить доступ к набору узлов с идентификаторами так же, как в настоящее время с xpath. Просто измените первый параметр 'оценивать' на' child' и xpath на '........ [@id]" ' – Alohci
. Xpath" .//node[@id] "в целевом элементе возвращает NodeList из только дочерние узлы. Скажем, цель « . Тогда только узлы с атрибутом id 102 и 103, но узел с id =" 101 "т.е. корень самого целевого элемента не возвращен, поэтому я сначала изменяю корень цели, а затем изменяю все дочерние узлы. Это выглядит не очень красиво. Именно поэтому я разбирался взад и вперед от xml до String. –
sony