2010-12-14 8 views
8

Ho bisogno di serializzare un oggetto java XML in un file XML utilizzando JAXB Marshaller (JAXB versione 2.2). Ora nell'oggetto XML, ho un tag che contiene valore stringa tale che:Gestione di caratteri di escape XML (ad es. Virgolette) utilizzando JAXB Marshaller

"<"tagA> 
**"<"YYYYY>done"<"/YYYYY>** 
"<"/tagA> 

Ora, come si può vedere che questo valore di stringa contiene di nuovo tag. Voglio che questo sia scritto nello stesso modo nel file xml.

Ma JAXB Marshaller converte questi valori quali:

"&"lt;YYYYY"&"gt;"&"#xD;done ... & così via

io non sono in grado di trattare questi caratteri di escape separatamente utilizzando JAXB 2.2 E 'possibile in ogni modo?

Qualsiasi aiuto in questo senso sarà grande ..

Grazie in anticipo, Abhinav Mishra

risposta

7

fatto impostando la seguente proprietà della JAXB Marshaller:

marshaller.setProperty("jaxb.encoding", "Unicode"); 
+0

puoi per favore approfondire il tuo utilizzo per sfuggire al personaggio. Non sono in grado di farlo con jus la proprietà impostata su unicode. –

+0

Per elaborare lo stesso, avevo appena impostato la seguente proprietà sul marshaller: marshaller.setProperty ("jaxb.encoding", "Unicode"); marshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty (CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler()); – javdev

+0

Qui nella terza affermazione, come potete vedere, ho creato una classe CustomCharacterEscapeHandler che sta effettivamente gestendo il carattere di escape. Puoi trovare facilmente il suo codice in rete cercando "come sovrascrivere il metodo di escape di CharacterEscapeHandler". Nel caso abbiate bisogno del codice, chiedetelo .. – javdev

2

è possibile sfruttare la struttura CDATA. Lo standard JAXB non copre questa struttura. C'è una estensione in EclipseLink JAXB (MOXy) per questo (io sono il capo tecnico). Guarda il mio risposta a una domanda relativa:

Esso descrive l'annotazione @XmlCDATA in Moxy:

import javax.xml.bind.annotation.XmlRootElement; 
import org.eclipse.persistence.oxm.annotations.XmlCDATA; 

@XmlRootElement(name="c") 
public class Customer { 

    private String bio; 

    @XmlCDATA 
    public void setBio(String bio) { 
     this.bio = bio; 
    } 

    public String getBio() { 
     return bio; 
    } 

} 

Per ulteriori informazioni si veda:

+0

Grazie per la risposta, Blaise. Esplorerò questo sicuramente perché sembra interessante. Tuttavia, ho trovato una soluzione per il mio problema che sto postando qui sotto. – javdev

1

A seconda di ciò che si sta esattamente cercando è possibile:

  • carattere disabilitare la fuga
  • o utilizzare CDATA stringa quale supporto può essere aggiunto in JAXB con un po 'di configurazione
6

C'è un modo più semplice.Prima sequenza uso escape personalizzato:

m.setProperty(CharacterEscapeHandler.class.getName(), new CharacterEscapeHandler() { 
    @Override 
    public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException { 
     out.write(ch, start, length); 
    } 
}); 

Poi maresciallo in una stringa come indicato di seguito

StringWriter writer = new StringWriter(); 
m.marshal(marshalObject, writer); 

e quindi creare un oggetto documento dallo scrittore di seguito indicate problema

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
InputSource is = new InputSource(new StringReader(writer.toString())); 
Document doc = builder.parse(is); 

caratteri di escape sarà risolto

+3

il problema di questo approccio è che non è possibile creare l'app con OpenJDK. com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler appartiene a Sun JDK. – walv

+0

È possibile utilizzare com.sun.xml.bind.marshaller.CharacterEscapeHandler – user2814648

0

Con il marshaller JAXB se si desidera il pieno controllo o ver quali caratteri sfuggire (ad es. "\ '") Si dovrà aggiungere proprietà:

Marshaller marshaller = jc.createMarshaller(); 
marshaller.setProperty(CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler()); 

e creare una nuova classe CustomCharacterEscapeHandler

import com.sun.xml.bind.marshaller.CharacterEscapeHandler; 

import java.io.IOException; 
import java.io.Writer; 

public class CustomCharacterEscapeHandler implements CharacterEscapeHandler { 

    public CustomCharacterEscapeHandler() { 
     super(); 
    } 

    public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException { 
     // avoid calling the Writerwrite method too much by assuming 
     // that the escaping occurs rarely. 
     // profiling revealed that this is faster than the naive code. 
     int limit = start+length; 
     for (int i = start; i < limit; i++) { 
      char c = ch[i]; 
      if(c == '&' || c == '<' || c == '>' || c == '\'' || (c == '\"' && isAttVal)) { 
       if(i!=start) 
        out.write(ch,start,i-start); 
       start = i+1; 
       switch (ch[i]) { 
        case '&': 
         out.write("&amp;"); 
         break; 
        case '<': 
         out.write("&lt;"); 
         break; 
        case '>': 
         out.write("&gt;"); 
         break; 
        case '\"': 
         out.write("&quot;"); 
         break; 
        case '\'': 
         out.write("&apos;"); 
         break; 
       } 
      } 
     } 

     if(start!=limit) 
      out.write(ch,start,limit-start); 
    } 
} 

Speranza che aiuta.