Avatar billede obix Nybegynder
24. november 2004 - 14:21 Der er 16 kommentarer og
1 løsning

Problemer med at kopiere en node i xml

Hej Eksperter.
Jeg har en node med en masse childs på. Den node vil jeg gerne læse ændre nogle af værdierne på og så sætte den ind i xmllen som en ny node. Så egentlig lave en kopi af noden hvordan gør jeg det?
Avatar billede simonvalter Praktikant
24. november 2004 - 14:26 #1
Avatar billede obix Nybegynder
24. november 2004 - 14:30 #2
jeg har prøvet at bruge node.cloneNode(true) men den ødelægger noden. Det er somom den sletter en masse data.
Avatar billede simonvalter Praktikant
24. november 2004 - 14:49 #3
hmm så ved jeg ikke lige hvordan man benytter den.
Avatar billede arne_v Ekspert
26. november 2004 - 23:21 #4
Det virker fint hos mig !

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

public class CreateAndClone {
    public static void main(String[] args) {
        try {
            OutputFormat fmt = new OutputFormat();
            fmt.setIndenting(true);
            XMLSerializer ser = new XMLSerializer(System.out, fmt);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.newDocument();
            Element all = doc.createElement("all");
            doc.appendChild(all);
            ser.serialize(doc);
            Element one1 = doc.createElement("one");
            one1.appendChild(doc.createTextNode("A"));
            one1.setAttribute("a1", "0");
            one1.setAttribute("a2", "1");
            all.appendChild(one1);
            ser.serialize(doc);
            Element one2 = (Element)one1.cloneNode(true);
            one2.getFirstChild().setTextContent("BB");
            one2.setAttribute("a2", "2");
            all.appendChild(one2);
            ser.serialize(doc);
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return;
    }
}

output:

<?xml version="1.0" encoding="UTF-8"?>
<all/>
<?xml version="1.0" encoding="UTF-8"?>
<all>
    <one a1="0" a2="1">A</one>
</all>
<?xml version="1.0" encoding="UTF-8"?>
<all>
    <one a1="0" a2="1">A</one>
    <one a1="0" a2="2">BB</one>
</all>
Avatar billede obix Nybegynder
27. november 2004 - 19:24 #5
Ahh Arne den måde du gør det på virker fint. Men....
Jeg har indtil nu brugt XPathAPI.selectSingleNode(/xpathtilnode); det virker fint før jeg har kopieret en node men ikke bagefter. Jeg har løst problemet ved hjælp af dit foreslag og jeg vil gerne give dig point for det men jeg vil meget gerne vide om det skal gøres anderledes hvis man vil bruge XPathAPI?
Avatar billede arne_v Ekspert
27. november 2004 - 20:24 #6
Jeg prøver at lege lidt med XPathAPI
Avatar billede arne_v Ekspert
27. november 2004 - 20:38 #7
Hm. Det her virker også hos mig:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xpath.XPathAPI;

public class CreateAndCloneXPath {
    public static void main(String[] args) {
        try {
            OutputFormat fmt = new OutputFormat();
            fmt.setIndenting(true);
            XMLSerializer ser = new XMLSerializer(System.out, fmt);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.newDocument();
            Element all = doc.createElement("all");
            doc.appendChild(all);
            ser.serialize(doc);
            Element one1 = doc.createElement("one");
            one1.appendChild(doc.createTextNode("A"));
            one1.setAttribute("a1", "0");
            one1.setAttribute("a2", "1");
            all.appendChild(one1);
            ser.serialize(doc);
            Element one1x = (Element)XPathAPI.selectSingleNode(doc.getDocumentElement(), "one[@a2='1']");
            Element one2 = (Element)one1x.cloneNode(true);
            one2.getFirstChild().setTextContent("BB");
            one2.setAttribute("a2", "2");
            all.appendChild(one2);
            ser.serialize(doc);
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return;
    }
}
Avatar billede arne_v Ekspert
27. november 2004 - 20:38 #8
og et svar
Avatar billede obix Nybegynder
27. november 2004 - 20:52 #9
Mit problem er at i dit eksempel kan jeg ikke bruge XPathAPI på one2 som er en klon af one1x... Er der en forklaring på det? undskyld hvis det ikke var tydeligt det var det mit problem var.
Avatar billede arne_v Ekspert
27. november 2004 - 20:57 #10
Det her virker også fint:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xpath.XPathAPI;

public class CreateAndCloneXPath {
    public static void main(String[] args) {
        try {
            OutputFormat fmt = new OutputFormat();
            fmt.setIndenting(true);
            XMLSerializer ser = new XMLSerializer(System.out, fmt);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.newDocument();
            Element all = doc.createElement("all");
            doc.appendChild(all);
            ser.serialize(doc);
            Element one1 = doc.createElement("one");
            one1.appendChild(doc.createTextNode("A"));
            one1.setAttribute("a1", "0");
            one1.setAttribute("a2", "1");
            all.appendChild(one1);
            ser.serialize(doc);
            Element one1x = (Element)XPathAPI.selectSingleNode(doc.getDocumentElement(), "one[@a2='1']");
            Element one2 = (Element)one1x.cloneNode(true);
            one2.getFirstChild().setTextContent("BB");
            one2.setAttribute("a2", "2");
            all.appendChild(one2);
            ser.serialize(doc);
            Element one2x = (Element)XPathAPI.selectSingleNode(doc.getDocumentElement(), "one[@a2='2']");
            Element one3 = (Element)one2x.cloneNode(true);
            one3.getFirstChild().setTextContent("CCC");
            one3.setAttribute("a2", "3");
            all.appendChild(one3);
            ser.serialize(doc);
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return;
    }
}
Avatar billede arne_v Ekspert
27. november 2004 - 20:58 #11
Eller vil du bruge one2 som første argument til selectSingleNode ?
Avatar billede obix Nybegynder
27. november 2004 - 21:03 #12
jeps lige præcist. Jeg vil bruge one2 som første argument
Avatar billede arne_v Ekspert
27. november 2004 - 21:16 #13
Før eller efter at du har appendet den ind i dokumentet ?
Avatar billede arne_v Ekspert
27. november 2004 - 21:26 #14
Det her virker faktisk:

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xpath.XPathAPI;

public class CreateAndCloneXPathExt {
    public static void main(String[] args) {
        try {
            OutputFormat fmt = new OutputFormat();
            fmt.setIndenting(true);
            XMLSerializer ser = new XMLSerializer(System.out, fmt);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.newDocument();
            Element all = doc.createElement("all");
            doc.appendChild(all);
            ser.serialize(doc);
            Element one1 = doc.createElement("one");
            one1.appendChild(doc.createTextNode("A"));
            one1.setAttribute("a1", "0");
            one1.setAttribute("a2", "1");
            all.appendChild(one1);
            ser.serialize(doc);
            Element one1x = (Element)XPathAPI.selectSingleNode(doc.getDocumentElement(), "one[@a2='1']");
            Element one2 = (Element)one1x.cloneNode(true);
            one2.getFirstChild().setTextContent("BB");
            one2.setAttribute("a2", "2");
            all.appendChild(one2);
            ser.serialize(doc);
            Element one2x = (Element)XPathAPI.selectSingleNode(one2, ".");
            Element one3 = (Element)one2x.cloneNode(true);
            one3.getFirstChild().setTextContent("CCC");
            one3.setAttribute("a2", "3");
            all.appendChild(one3);
            ser.serialize(doc);
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return;
    }
}
Avatar billede arne_v Ekspert
27. november 2004 - 21:27 #15
Men altså antallet af forskellige måder at gøre det på og forskellige
versioner af Xalan er astronomiske, så ...
Avatar billede obix Nybegynder
27. november 2004 - 21:48 #16
Jeg prøver på at gøre det før jeg har appendet det til dokumentet. Det er måske derfor det ikke vil virke?
Avatar billede arne_v Ekspert
27. november 2004 - 21:50 #17
Hos mig virker det faktisk både før og efter.

Men jeg spekulerede på om der var et problem med en node som faktisk ikke
var indsat i et dokument.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester