J'utilise une fonction qui prend en charge deux éléments DOM - parent et enfant provenant de différents documents. J'importe l'élément enfant, le transforme, puis l'ajoute à l'élément parent. Mais, la dernière ligne du code suivant lève une exception dom: org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: un noeud est utilisé dans un document différent de celui qui l'a créé.Transformation et ajout d'un noeud Dom
S'il vous plaît voir mon code ci-dessous:
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);
}
Après avoir importé le noeud initialement, je ne suis pas sûr de savoir comment transformer les ID de manière récursive. Si le nœud a plusieurs sous-niveaux (2 sous-niveaux dans mon exemple) alors est-ce que je fais une boucle récursivement à travers chaque niveau? – sony
Oui, vous pouvez parcourir l'arborescence DOM avec une récursivité, ou vous pouvez accéder à l'ensemble des nœuds avec des ID de la même manière que vous le faites actuellement avec un xpath. Changez simplement le premier paramètre de 'evaluate' en' child' et le xpath en '" .// node [@id] "' – Alohci
Le xpath ".//node[@id]" sur l'élément cible retourne un NodeList de seulement les nœuds enfants. Dites que la cible est " Ensuite seulement les nœuds avec les identifiants 102 et 103 mais le nœud avec id =" 101 "ie la racine de l'élément cible lui-même n'est pas retournée, donc je modifie d'abord la racine de la cible, puis je modifie tous les nœuds enfants, ce qui n'est pas très joli, c'est pourquoi j'ai analysé xml en String. –
sony