2010-06-08 5 views
7

Sto cercando di scrivere i dati XML utilizzando Stax dove il contenuto stesso è HTMLCome faccio a scrivere XML senza caratteri di escape al di fuori di un CDATA

Se provo

xtw.writeStartElement("contents"); 
xtw.writeCharacters("<b>here</b>"); 
xtw.writeEndElement(); 

ottengo questo

<contents>&lt;b&gt;here&lt;/b&gt;</contents> 

Quindi noto il metodo CDATA e cambio il mio codice in:

xtw.writeStartElement("contents"); 
xtw.writeCData("<b>here</b>"); 
xtw.writeEndElement(); 

e questa volta il risultato è

<contents><![CDATA[<b>here</b>]]></contents> 

che non è ancora buono. Quello che davvero voglio è

<contents><b>here</b></contents> 

Quindi c'è un API XML/libreria che mi permette di scrivere testo grezzo senza essere in una sezione CDATA? Finora ho guardato Stax e JDom e loro non sembrano offrire questo.

Alla fine potrei ricorrere al buon vecchio StringBuilder ma questo non sarebbe elegante.

Aggiornamento:

Sono d'accordo con la maggior parte delle risposte finora. Tuttavia, invece di <b>here</b>, potrei avere un documento HTML da 1 MB che voglio incorporare in un documento XML più grande. Quello che suggerisci significa che devo analizzare questo documento HTML per comprenderne la struttura. Vorrei evitare questo se possibile.

Risposta:

Non è possibile, altrimenti si potrebbe creare documenti XML non validi.

+2

Se ciò fosse possibile, è possibile scrivere troppo facilmente file XML non validi. Non che la maggior parte del mondo reale HTML (che non sia XHTML) sia ** non ** XML valido (troppi tag non chiusi e attributi senza escape). Tutto ciò va bene per HTML, ma non è permesso per XML, quindi usare CDATA è davvero l'unica cosa corretta da fare, a meno che il tuo HTML sia in realtà XHTML. –

+0

@ Joachim. Sì nel mio caso è XHTML. Questo è il motivo per cui so che è valido e voglio incorporarlo subito senza alcuna elaborazione. – kazanaki

risposta

3

Il problema è che non è il testo grezzo è un elemento così si dovrebbe scrivere

xtw.writeStartElement("contents"); 
xtw.writeStartElement("b"); 
xtw.writeCData("here"); 
xtw.writeEndElement(); 
xtw.writeEndElement(); 
+0

Penso che il problema sia che ha un blob che può contenere tag. – ShiDoiSi

0

Il problema non è "qui", è <b></b>.

Aggiungi l'elemento <b> come contenuto secondario e sarai in grado di farlo. Qualsiasi libreria come JDOM o DOM4J ti consentirà di farlo. Il caso generale è di analizzare il contenuto in un DOM XML e aggiungere l'elemento radice come figlio di <contents>.

Non è possibile aggiungere valori di escape fuori da una sezione CDATA.

0

Se il XML e HTML non sono troppo grandi, si potrebbe fare una soluzione alternativa:

xtw.writeStartElement("contents"); 
xtw.writeCharacters("anUniqueIdentifierForReplace"); // <-- 
xtw.writeEndElement(); 

Quando hai il tuo XML come una stringa:

xmlAsString.replace("anUniqueIdentifierForReplace", yourHtmlAsString); 

lo so, non è così bello, ma questo potrebbe funzionare.


Modifica: Naturalmente, è necessario verificare se yourHtmlAsString è valido.

+0

Molto intelligente! Grazie per questa idea. – kazanaki

+1

Questo è in realtà un hack molto scortese. Se non si desidera che il writer XML produca un documento XML valido, utilizzare invece la concatenazione String per iniziare. – jarnbjo

+1

Se si sa di avere un XML valido da inserire come un blob, questo funzionerebbe, ma si corre il rischio che sia tutto ben formato. – Mark

0

Se si desidera incorporare un documento HTML di grandi dimensioni in un documento XML, l'imho di CDATA è la strada da percorrere. In questo modo non devi comprendere o elaborare la struttura interna e in seguito puoi cambiare il tipo di documento da HTML a qualcos'altro senza troppi problemi. Anche Penso che non puoi incorporare ad es. Istruzioni DOCTYPE direttamente (cioè come dati strutturati che mantengono la semantica dell'istruzione DOCTYPE). Devono essere rappresentati come personaggi.

(Questo è principalmente una risposta al tuo aggiornamento, ma purtroppo non ho abbastanza rep per commentare ...............)

1

Se si desidera che l'XML per essere incluso AS XML e non come dati di carattere, quindi deve essere analizzato ad un certo punto. Se non si desidera eseguire manualmente l'analisi manualmente, si hanno due alternative:

(1) Utilizza entità esterne analizzate: in questo caso il file esterno verrà estratto e analizzato dal parser XML. Quando l'output viene nuovamente serializzato, includerà il contenuto del file esterno.

[Vedi http://www.javacommerce.com/displaypage.jsp?name=entities.sql&id=18238]

(2) Usare XInclude - in questo caso il file deve essere eseguito attraverso un processore XInclude che unire i riferimenti XInclude in uscita. La maggior parte dei processori xslt e xmllint eseguono anche xinclude con un'opzione appropriata.

[Vedi: http://www.xml.com/pub/a/2002/07/31/xinclude.html]

(XSLT può anche essere usato per unire documenti senza utilizzare la sintassi XInclude XInclude solo fornisce una sintassi standard.)

0

non vedo quale sia il problema con l'analisi il grande blocco di XML che vuoi inserire nel tuo output. Utilizzare un parser StAX per analizzarlo e basta scrivere codice per inoltrare tutti gli eventi al serializzatore esistente (variabile "xtw").

0

Se il blob di HTML è in realtà xhtml quindi suggerirei di fare qualcosa di simile (in pseudo-codice):

xtw.writeStartElement("contents") 
XMLReader xtr=new XMLReader(); 
xtr.read(blob); 
Dom dom=xtr.getDom(); 
for(element e:dom){ 
    xtw.writeElement(e); 
} 
xtw.writeEndElement(); 

o qualcosa di simile. Ho dovuto fare qualcosa di simile una volta ma ho usato una libreria diversa.