2009-05-15 12 views
7

Nella mia applicazione, ho alterare una parte del file XML, che iniziano in questo modo:Come mantenere gli spazi bianchi prima dell'elemento del documento durante l'analisi con Java?

<?xml version="1.0" encoding="UTF-8"?> 
<!-- $Id: version control yadda-yadda $ --> 

<myElement> 
... 

Nota la riga vuota prima <myElement>. Dopo il caricamento, alterazione e risparmio, il risultato è tutt'altro che gradevole:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- $Id: version control yadda-yadda $ --><myElement> 
... 

ho scoperto che lo spazio bianco (una nuova riga) tra la testa e il nodo documento non è rappresentato nel DOM affatto. Il seguente codice autonomo riproduce il problema in modo affidabile:

String source = 
    "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<!-- foo -->\n<empty/>"; 
byte[] sourceBytes = source.getBytes("UTF-16"); 

DocumentBuilder builder = 
    DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document doc = 
    builder.parse(new ByteInputStream(sourceBytes, sourceBytes.length)); 

DOMImplementationLS domImplementation = 
    (DOMImplementationLS) doc.getImplementation(); 
LSSerializer lsSerializer = domImplementation.createLSSerializer(); 
System.out.println(lsSerializer.writeToString(doc)); 

// output: <?xml version="1.0" encoding="UTF-16"?>\n<!-- foo --><empty/> 

Qualcuno ha un'idea di come evitare questo? Essenzialmente, voglio che l'output sia lo stesso dell'input. (So ​​che la dichiarazione xml verrà rigenerata perché non fa parte del DOM, ma non è un problema qui.)

+1

Ho finito per hackerarlo nell'output utilizzando una classe OutputStream personalizzata che cerca la prima occorrenza di "-><" e aggiunge due newline; Io uso questo flusso solo se il primo nodo figlio del documento è in realtà un commento. Ancora un hack, ma almeno perfettamente incapsulato :-) –

+0

Ho lo stesso problema. Potresti per favore aiutare? http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

risposta

2

La causa principale è che lo standard DOM Level 3 non può rappresentare i nodi di testo come figli di un documento senza rompere la spec. Gli spazi bianchi verranno eliminati da qualsiasi parser compatibile.

Document -- 
    Element (maximum of one), 
    ProcessingInstruction, 
    Comment, 
    DocumentType (maximum of one) 

Se avete bisogno di una soluzione conforme agli standard e l'obiettivo è invece di leggibilità riproduzione 100%, vorrei cercare nel vostro meccanismo di uscita.

+0

Buona risposta, ma questo è uno stupido bug nelle specifiche a mio avviso. Puoi sicuramente inviare del testo prima dell'elemento del documento, ma non puoi inserirlo? – Archie

+0

@McDowell qualsiasi cosa possiamo fare per evitare questo, per favore guarda nella mia domanda. http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

1

In generale, gli spazi bianchi sono considerati irrilevanti in XML e pertanto non vengono conservati quando viene analizzato un file XML . La maggior parte delle librerie che generano XML hanno un'opzione per l'output con una buona formattazione e indentazioni corrette ma sarà sempre abbastanza generica. No "avere una linea in più a destra qui".

+1

Il punto è che * era * una riga nell'input originale, e dovrebbe essere mantenuta, come nel caso di tutti gli spazi bianchi nel resto del documento! –

3

Perché vuoi evitare questo?

Il white-space al di fuori del tag/elementi è definito come insignificanti dalle specifiche. Semplicemente non esiste, per quanto riguarda l'infoset che è rappresentato dal tuo DOM.

conseguenza, sulla serializzazione nuovamente il DOM, non sarà lì.

Se siete nel processo di sviluppo di qualcosa che si basa su questa linea vuota ... non.

+0

Nessun programma si basa su questo formato, ovviamente. Tuttavia, i file contengono dati di traduzione; sono registrati per il controllo della versione e mantenuti costantemente. Pertanto, sarebbe bello visualizzare le differenze se le uniche modifiche apportate alla mia app sono intenzionali. –

+0

Ho pensato così ... Penso che l'unico modo sensato di trattare con questo non è quello di avere questa riga vuota nei file per iniziare. Non penso che ci sia qualche metodo raccomandabile per mantenere questa linea. Forse i file dovrebbero essere di regola passati attraverso uno strumento di riordino prima di effettuare il check-in per evitare queste incoerenze. – Tomalak

+0

@Tomalak :: Potete aiutarmi: http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

6

Ho avuto lo stesso problema. La mia soluzione era scrivere il mio parser XML: DecentXML

Caratteristica principale: può conservare al 100% l'input originale, spazi bianchi, entità, tutto. Non ti darà fastidio con i dettagli, ma se il tuo codice ha bisogno di generare XML come questo:

<element 
    attr="some complex value" 
    /> 

quindi puoi.

+0

Grazie per il suggerimento; DecentXML sembra certamente una buona cosa da tenere a mente! * bookmarksIt * Buono a vedere che almeno uno dei progetti "ancora-un-altro-parser" ha davvero una buona ragione per esistere. Tuttavia, per il mio problema attuale, preferirei rimanere con l'API DOM standard per tutto il mio codice di elaborazione e aggiungere semplicemente la linea nella fase di output. –

+0

Quindi è necessario aggiungere manualmente i nodi di testo prima dell'elemento radice. Osserva l'oggetto Document come aggiungere nodi normali (non-elementali). Se ciò non è possibile, è necessario creare un filtro per il writer/flusso di output che esegue l'hacking della newline. –

+0

@AaronDigulla :: Puoi aiutarmi in questo http://stackoverflow.com/questions/30940162/dom-parser-wrong-childnodes-count – user3930361

0

Sono d'accordo con Kris e Tomalak, la riga vuota, non è rilevante dal punto di vista XML. Se l'applicazione deve produrre una riga vuota nell'output, suggerirei di rivedere la necessità di tale requisito.

In ogni caso, se si vuole ancora che appaia riga vuota, vorrei suggerire di scaricare il codice sorgente del parser XML che si sta utilizzando e modificare tale comportamento. Ma tieni presente che questo non è XML standard e non sarà compatibile con altre applicazioni.

+1

Che dire dei file XML che devono essere modificati dagli esseri umani? In tal caso, la formattazione originale è importante. XML non è solo per la serializzazione, se fosse allora un formato binario sarebbe meglio. – MarioVilas

Problemi correlati