/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
XML/DOM
Fra : Frederik Hansen


Dato : 05-09-02 16:32

Hejsa

Hvis jeg har en masse XML filer som alle overholder en DTD, hvordan kan
jeg så få dem alle sammen samlet i en XML fil, som statid over holder
samme DTD? Helt præsigt, hvordan laver jeg et nyt document, hvor jeg
sætter de to linier:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE superEntity SYSTEM "http://localhost:8000/Entities.dtd" >

og derefter kopiere hele noder fra source xml-documentet til
target-documentet. Jeg prøvede noget ligende dette :

for (int i = 0; i < xmlList.length; i++)
{
Document document = builder.parse(new InputSource (new
FileInputStream(xmlList[i])));

NodeList nodes = document.getElementsByTagName("entity");
for (int j = 0; j < nodes.getLength(); j++)
{
org.w3c.dom.Node node = nodes.item(j);
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
resultRoot.appendChild(node);
}
}

Men det giver en WRONG_DOCUMENT_ERR i appendChild linie, og det skulle
betyde at node ikke kommer fra det document som jeg prøver at adde den
til, og det er jo ligesom hele ideen at det ikke er.. Så jeg prøvede at
lave en cloneNode(true), men det ændrede ikke noget..

--
Venlig hilsen

Frederik Hansen

Sun Certified Programmer
for the Java(tm) 2 Platform

email : frederik@roirex.dk
www : www.roirex.dk


 
 
Morten Primdahl (05-09-2002)
Kommentar
Fra : Morten Primdahl


Dato : 05-09-02 16:47

Frederik Hansen wrote:
> Hejsa
>
> Hvis jeg har en masse XML filer som alle overholder en DTD, hvordan kan
> jeg så få dem alle sammen samlet i en XML fil, som statid over holder
> samme DTD? Helt præsigt, hvordan laver jeg et nyt document, hvor jeg
> sætter de to linier:
>
> <?xml version="1.0" encoding="UTF-8" ?>
> <!DOCTYPE superEntity SYSTEM "http://localhost:8000/Entities.dtd" >
>
> og derefter kopiere hele noder fra source xml-documentet til
> target-documentet. Jeg prøvede noget ligende dette :
>
> for (int i = 0; i < xmlList.length; i++)
> {
> Document document = builder.parse(new InputSource (new
> FileInputStream(xmlList[i])));
>
> NodeList nodes = document.getElementsByTagName("entity");
> for (int j = 0; j < nodes.getLength(); j++)
> {
> org.w3c.dom.Node node = nodes.item(j);
> if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
> resultRoot.appendChild(node);
> }
> }
>
> Men det giver en WRONG_DOCUMENT_ERR i appendChild linie, og det skulle
> betyde at node ikke kommer fra det document som jeg prøver at adde den
> til, og det er jo ligesom hele ideen at det ikke er.. Så jeg prøvede at
> lave en cloneNode(true), men det ændrede ikke noget..
>

Det er ikke lovligt at lave appends på kryds og tværs af DOM objekter.
Prøv org.w3c.dom.Document.importNode(Node node, boolean deep);

Fex:

for(int i=0; i<xmlList.length; i++)
{
Document document =
builder.parse(new InputSource (new FileInputStream(xmlList[i])));

newDocument.importNode(document.getDocumentElement());
}

Mvh Morten


Frederik Hansen (05-09-2002)
Kommentar
Fra : Frederik Hansen


Dato : 05-09-02 18:35

Hej Morten

Mmh, det kan jeg ikke se komme til at virke, for det tilføjer jo til
documentet, men det vil jeg ikke. Mine filer ser sådan ud:

<entity>
   <subEntity/>
</entity>

og jeg vil gerne have outputet til at blive

<superEntity>
<entity>
   <subEntity/>
</entity>
<entity>
   <subEntity/>
</entity>
</superEntity>

Og hvordan gemmer man det samlet document. toString() på et Dokument er
ikke overskrevet ligesom en Node's..

Morten Primdahl wrote:

> Frederik Hansen wrote:
>
>> Hejsa
>>
>> Hvis jeg har en masse XML filer som alle overholder en DTD, hvordan
>> kan jeg så få dem alle sammen samlet i en XML fil, som statid over
>> holder samme DTD? Helt præsigt, hvordan laver jeg et nyt document,
>> hvor jeg sætter de to linier:
>>
>> <?xml version="1.0" encoding="UTF-8" ?>
>> <!DOCTYPE superEntity SYSTEM "http://localhost:8000/Entities.dtd" >
>>
>> og derefter kopiere hele noder fra source xml-documentet til
>> target-documentet. Jeg prøvede noget ligende dette :
>>
>> for (int i = 0; i < xmlList.length; i++)
>> {
>> Document document = builder.parse(new InputSource (new
>> FileInputStream(xmlList[i])));
>>
>> NodeList nodes = document.getElementsByTagName("entity");
>> for (int j = 0; j < nodes.getLength(); j++)
>> {
>> org.w3c.dom.Node node = nodes.item(j);
>> if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
>> resultRoot.appendChild(node);
>> }
>> }
>>
>> Men det giver en WRONG_DOCUMENT_ERR i appendChild linie, og det skulle
>> betyde at node ikke kommer fra det document som jeg prøver at adde den
>> til, og det er jo ligesom hele ideen at det ikke er.. Så jeg prøvede
>> at lave en cloneNode(true), men det ændrede ikke noget..
>>
>
> Det er ikke lovligt at lave appends på kryds og tværs af DOM objekter.
> Prøv org.w3c.dom.Document.importNode(Node node, boolean deep);
>
> Fex:
>
> for(int i=0; i<xmlList.length; i++)
> {
> Document document =
> builder.parse(new InputSource (new FileInputStream(xmlList[i])));
>
> newDocument.importNode(document.getDocumentElement());
> }
>
> Mvh Morten
>


--
Venlig hilsen

Frederik Hansen

Sun Certified Programmer
for the Java(tm) 2 Platform

email : frederik@roirex.dk
www : www.roirex.dk


Morten (05-09-2002)
Kommentar
Fra : Morten


Dato : 05-09-02 19:38

Frederik Hansen wrote:
> Hej Morten
>
> Mmh, det kan jeg ikke se komme til at virke, for det tilføjer jo til
> documentet, men det vil jeg ikke. Mine filer ser sådan ud:
>
> <entity>
> <subEntity/>
> </entity>
>
> og jeg vil gerne have outputet til at blive
>
> <superEntity>
> <entity>
> <subEntity/>
> </entity>
> <entity>
> <subEntity/>
> </entity>
> </superEntity>
>
> Og hvordan gemmer man det samlet document. toString() på et Dokument er
> ikke overskrevet ligesom en Node's..

Ved du hvad du kan forvente af Node typer? Du kan evt. gøre således, at
du for hvert dokument du loader gennem builder.parse(..), starter
med dets documentElement, og traverserer hele dokumentet, og så
"kopierer" dine noder. Noget a la:

superDocument = ...; //global

loadDocs() {
Document doc = builder.parse(...);

Element e = doc.getDocumentElement();

if(e != null) {
superDocument.getDocumentElement().appendChild(resolveElement(e));
}
}

public Node resolveNode(Node n) {
if(n.getNodeType() == Node.ELEMENT_NODE) {
return resolveElement((Element)n);
}
else if(n.getNodeType() == Node.TEXT_NODE) {
return resolveText((Text)n);
}
else throw new UnsupportedNodeTypeException();
}

public Element resolveElement(Element e) {
Element clone = superDocument.createElement(e.getTagName());

NodeList children = e.getChildNodes();

for(int i=0; i<children.getLength(); i++) {
clone.appendChild(resolveNode(children.item(i)));
}

return clone;
}

public Text resolveText(Text t) {
return superDocument.createTextNode(t.getValue());
}

.. andre node typer her :)

Det er en lidt mere omstændig måde at løse det på. Alternativet til den
er, at du skriver din egen ContentHandler implementation og laver en SAX
løsning. Når du skal lave et "dump" af dit Document object, er der flere
muligheder. Hvis du bruger Xerces, er der en XMLSerializer klasse.
Alternativt kan du igen bruge ovenstående strategi til at skrive din
egen serializer.

Mvh Morten




> Morten Primdahl wrote:
>
>> Frederik Hansen wrote:
>>
>>> Hejsa
>>>
>>> Hvis jeg har en masse XML filer som alle overholder en DTD, hvordan
>>> kan jeg så få dem alle sammen samlet i en XML fil, som statid over
>>> holder samme DTD? Helt præsigt, hvordan laver jeg et nyt document,
>>> hvor jeg sætter de to linier:
>>>
>>> <?xml version="1.0" encoding="UTF-8" ?>
>>> <!DOCTYPE superEntity SYSTEM "http://localhost:8000/Entities.dtd" >
>>>
>>> og derefter kopiere hele noder fra source xml-documentet til
>>> target-documentet. Jeg prøvede noget ligende dette :
>>>
>>> for (int i = 0; i < xmlList.length; i++)
>>> {
>>> Document document = builder.parse(new InputSource (new
>>> FileInputStream(xmlList[i])));
>>>
>>> NodeList nodes = document.getElementsByTagName("entity");
>>> for (int j = 0; j < nodes.getLength(); j++)
>>> {
>>> org.w3c.dom.Node node = nodes.item(j);
>>> if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
>>> resultRoot.appendChild(node);
>>> }
>>> }
>>>
>>> Men det giver en WRONG_DOCUMENT_ERR i appendChild linie, og det
>>> skulle betyde at node ikke kommer fra det document som jeg prøver at
>>> adde den til, og det er jo ligesom hele ideen at det ikke er.. Så jeg
>>> prøvede at lave en cloneNode(true), men det ændrede ikke noget..
>>>
>>
>> Det er ikke lovligt at lave appends på kryds og tværs af DOM objekter.
>> Prøv org.w3c.dom.Document.importNode(Node node, boolean deep);
>>
>> Fex:
>>
>> for(int i=0; i<xmlList.length; i++)
>> {
>> Document document =
>> builder.parse(new InputSource (new FileInputStream(xmlList[i])));
>>
>> newDocument.importNode(document.getDocumentElement());
>> }
>>
>> Mvh Morten
>>
>
>



Niels Ull Harremoës (09-09-2002)
Kommentar
Fra : Niels Ull Harremoës


Dato : 09-09-02 21:48

Du kunne jo prøve den helt "dumme" løsning med en SequenceInputStream, hvor
du bare læser filerne i rækkefølge:

byte[] prefix = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><!DOCTYPE
superEntity SYSTEM
\"http://localhost:8000/Entities.dtd\">".getBytes("UTF-8");
byte[] postfix = "</superentity>".getBytes("UTF-8");
List inputs = new LinkedList();
inputs.add(new ByteArrayInputStream(prefix));

for (int i = 0; i < xmlList.length; i++) {
inputs.add(new FileInputStream(xmlList[i]));
}
inputs.add(new ByteArrayInputStream(postfix));

Document document = builder.parse(new InputSource (new
SequenceInputStream(inputs.iterator()));

Det går selvfølgelig skidt, hvis de enkelte filer indeholder <?xml...?> osv.
En lidt mere elegant implementation ville lave en anonym klasse, der
implementerer Iterator - så behøver du ikke åbne alle filerne på forhånd.

Iterator it_inputs = new Iterator() {
final byte[] prefix = "<?xml version=\"1.0\" encoding=\"UTF-8\"
?><!DOCTYPE superEntity SYSTEM
\"http://localhost:8000/Entities.dtd\">".getBytes("UTF-8");
final byte[] postfix = "</superentity>".getBytes("UTF-8");
int count = -1;
public boolean hasNext() { return count <= xmlList.length+1; }
public void remove() throws UnsupportedOperationException { throw new
UnsupportedOperationException() };
public Object next() thorws NoSuchElementException {
count++;
if (count == 0 ) {
return new ByteArrayInputStream(prefix);
}else if (count <= xmlList.length) {
return new FileInputStream(xmlList[count-1]);
} else if (count == xmlList.length+1) {
return new ByteArrayInputStream(postfix);
} else throw new NoSuchElementException();
}
}

Document document = builder.parse(new InputSource (new
SequenceInputStream(it_inputs);


God fornøjelse!

Niels Harremoës



Søg
Reklame
Statistik
Spørgsmål : 177501
Tips : 31968
Nyheder : 719565
Indlæg : 6408521
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste