2010-12-14 18 views
8

Potrzebuję do serializacji obiektu XML java do pliku XML za pomocą JAXB Marshaller (JAXB wersja 2.2). Teraz w obiekt XML, mam znacznik, który zawiera String wartość takie, że:Obsługa znaków kontrolnych XML (np. Cytatów) przy użyciu JAXB Marshaller

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

Teraz jak widać, że wartość ta zawiera tagów ciąg ponownie. Chcę, aby to było napisane w taki sam sposób w pliku xml.

Ale JAXB naziemnego konwertuje te wartości, takich jak:

"&"lt;YYYYY"&"gt;"&"#xD;done ... & itd

nie jestem w stanie traktować te znaki ewakuacyjne oddzielnie przy użyciu JAXB 2.2 Czy to możliwe, tak czy inaczej?

Każda pomoc w tym zakresie będzie wielki ..

Dzięki z góry, Abhinav Mishra

Odpowiedz

7

Sporządzono go przez ustawienie następującą właściwość dla JAXB naziemnego:

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

Czy możesz rozwikłać swoje zastosowanie, aby uciec z charatcer. Nie mogę tego zrobić, gdy właściwość ustawiona jest na Unicode. –

+0

Aby rozwinąć to samo, właśnie ustawiłem właściwość marshaller: marshaller.setProperty ("jaxb.encoding", "Unicode"); marshaller.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty (CharacterEscapeHandler.class.getName(), new CustomCharacterEscapeHandler()); – javdev

+0

Tutaj, w trzeciej części, jak widzisz, utworzyłem klasę CustomCharacterEscapeHandler, która faktycznie wykonuje obsługę znaków escape. Kod można łatwo znaleźć w Internecie, przeszukując "jak zastąpić metodę escape w CharacterEscapeHandler". Jeśli potrzebujesz kodu, zapytaj mnie .. – javdev

2

Można wykorzystać strukturę CDATA. Standardowy JAXB nie obejmuje tej struktury. Dla tego jest rozszerzenie w EclipseLink JAXB (MOXy) (jestem liderem technicznym). Sprawdź moją odpowiedź na pytanie pokrewnej:

Opisuje adnotacji @XmlCDATA w 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; 
    } 

} 

Aby uzyskać więcej informacji, patrz:

+0

Dzięki za odpowiedź Blaise. Z pewnością odkryję to na własne oczy, ponieważ wydaje się interesujące. Jednak znalazłem rozwiązanie dla mojego problemu, który zamieszczam poniżej .. – javdev

1

W zależności od tego, czego dokładnie szuka możesz:

  • wyłączyć ucieczki znaków
  • lub użyć CDATA łańcuch, który można dodać do JAXB z niewielką konfiguracją
6

Jest jeden prostszy sposób.Pierwsza sekwencja wykorzystanie niestandardowych ucieczki:

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); 
    } 
}); 

Następnie marszałek go na ciąg jak wspomniano poniżej

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

a następnie utworzyć obiekt dokumentu z pisarzem wymienionych poniżej

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

znaków ucieczki emisji zostanie rozwiązany:

+3

problem polega na tym, że nie można zbudować aplikacji z OpenJDK. com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler należy do Sun JDK. – walv

+0

Możesz użyć com.sun.xml.bind.marshaller.CharacterEscapeHandler – user2814648

0

Z joystickiem JAXB, jeśli chcesz uzyskać pełną kontrolę ver, które znaki uciec (np. "\ '") Trzeba będzie dodać właściwość:

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

i stworzyć nową klasę 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); 
    } 
} 

nadzieję, że pomoże.

Powiązane problemy