2014-06-05 5 views
11

Come preparare XML con CDATA,Come aggiungere <! [CDATA [e]]> in XML preparato da JAXB

sto preraring questa risposta via JAXB,

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> 
<SOAP-ENV:Header/> 
<soapenv:Body> 
    <tem:RequestData> 
    <tem:requestDocument> 
     <![CDATA[ 
     <Request> 
      <Authentication CMId="68" Function="1" Guid="5594FB83-F4D4-431F-B3C5-EA6D7A8BA795" Password="poihg321TR"/> 
      <Establishment Id="4297867"/> 
     </Request> 
     ]]> 
     </tem:requestDocument> 
    </tem:RequestData> 
</soapenv:Body> 
</soapenv:Envelope> 

Ma da JAXB i non sto ottenendo CDATA, come mettere CDATA all'interno elemento <tem:requestDocument>.

Ecco il mio codice Java:

public static String test1() { 
    try { 
     initJB(); 
     String response = null; 
     StringBuffer xmlStr = null; 
     String strTimeStamp = null; 
     com.cultagent4.travel_republic.gm.Envelope envelope = null; 
     com.cultagent4.travel_republic.gm.Header header = null; 
     com.cultagent4.travel_republic.gm.Body body = null; 
     com.cultagent4.travel_republic.gm.RequestData requestData = null; 
     com.cultagent4.travel_republic.gm.RequestDocument requestDocument = null; 
     com.cultagent4.travel_republic.gm.RequestDocument.Request request = null; 
     com.cultagent4.travel_republic.gm.RequestDocument.Request.Authentication authentication = null; 
     com.cultagent4.travel_republic.gm.RequestDocument.Request.Establishment establishment = null; 

     ObjectFactory objFact = new ObjectFactory(); 
     envelope = objFact.createEnvelope(); 
     header = objFact.createHeader(); 
     envelope.setHeader(header); 
     body = objFact.createBody(); 
     requestData = objFact.createRequestData(); 


     requestDocument = objFact.createRequestDocument(); 
     request = new RequestDocument.Request(); 

     authentication = new RequestDocument.Request.Authentication(); 
     authentication.setCMId("68"); 
     authentication.setGuid("5594FB83-F4D4-431F-B3C5-EA6D7A8BA795"); 
     authentication.setPassword("poihg321TR"); 
     authentication.setFunction("1"); 
     request.setAuthentication(authentication); 
     establishment = new RequestDocument.Request.Establishment(); 
     establishment.setId("4297867"); 
     request.setEstablishment(establishment); 
     requestDocument.setRequest(request); 
     requestData.setRequestDocument(requestDocument); 
     body.setRequestData(requestData); 
     envelope.setBody(body); 



     jaxbMarshallerForBase = jaxbContextForBase.createMarshaller(); 
     OutputStream os = new ByteArrayOutputStream(); 


     System.out.println(); 
     // output pretty printed 

//    jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
//    jaxbMarshallerForBase.marshal(envelope, System.out); 
//    jaxbMarshallerForBase.marshal(envelope, os); 


     jaxbMarshallerForBase.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); 
     jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
//   jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); 
// get an Apache XMLSerializer configured to generate CDATA 
     XMLSerializer serializer = getXMLSerializer(); 


// marshal using the Apache XMLSerializer 
     SAXResult result = new SAXResult(serializer.asContentHandler()); 

     System.out.println("*************"); 
     jaxbMarshallerForBase.marshal(envelope, result); 
     System.out.println("--------------"); 



     return null; 
    } catch (JAXBException ex) { 
     Logger.getLogger(GM_TravelRepublic.class.getName()).log(Level.SEVERE, null, ex); 
    } finally { 
     return null; 
    } 
} 

private static XMLSerializer getXMLSerializer() { 
    // configure an OutputFormat to handle CDATA 
    OutputFormat of = new OutputFormat(); 

    // specify which of your elements you want to be handled as CDATA. 
    // The use of the ; '^' between the namespaceURI and the localname 
    // seems to be an implementation detail of the xerces code. 
    // When processing xml that doesn't use namespaces, simply omit the 
    // namespace prefix as shown in the third CDataElement below. 
    of.setCDataElements(new String[]{"^Request","^Authentication","^Establishment"}); 


    // set any other options you'd like 
    of.setPreserveSpace(true); 
    of.setIndenting(true); 


    StringWriter writer = new StringWriter(); 
    // create the serializer 
    XMLSerializer serializer = new XMLSerializer(of); 


    serializer.setOutputByteStream(System.out); 


    return serializer; 
} 

Qui io sono sempre lo stesso xml, ma senza CDATA. Il mio server non accetta la richiesta senza CDATA.Aiuta l'aiuto.

risposta

0

penso che nel metodo private static XMLSerializer getXMLSerializer() si sta impostando sbagliato i CDATA elementi, perché il vostro elemento CDATA è <tem:requestDocument> invece di RequestAuthentication e Establishment che sono il contenuto. Prova con:

of.setCDataElements(new String[]{"tem^requestDocument","http://tempuri.org/^requestDocument","requestDocument"}); 

invece di:

of.setCDataElements(new String[]{"^Request","^Authentication","^Establishment"}); 

Spero che questo aiuti,

+0

no :(http://pastie.org/9542832 – LMK

+0

Ops scusate @ LMK. Sono sicuro che questo è il modo, potrebbe essere mi sbagliavo specificando i nomi corrispondenti (non ricordo l'esatto sintassi), prova con: 'of.setCDataElements (new String [] {" ns3^requestDocument ","^requestDocument "," ns3: requestDocument "});', aggiorno anche la risposta. Spero che questa volta sia più utile – albciff

+0

no :(http://pastie.org/9552273 – LMK

1

CDATA è dati di carattere, sembra che il tuo server vuole la parte del XML a partire da Request di entrare come testo Potrebbe essere sufficiente creare XmlAdapter per convertire l'istanza di Request in un String. I caratteri risultanti saranno sfuggiti non in CDATA ma questo maggio si adatta al tuo caso d'uso.

Poi, se si ha realmente bisogno come CDATA in aggiunta al XmlAdapter è possibile applicare una delle strategie descritte nel link qui sotto:

0

Dal setCDataElements method description nella documentazione di Apache :

Sets the list of elements for which text node children should be output as CDATA.

Quello che penso ° a mezzi è, i bambini dell'elemento tem:requestDocument dovrebbero essere tutti parte di un singolo blocco di testo (e non gli elementi xml da soli) affinché funzioni. Una volta fatto, probabilmente un semplice

of.setCDataElements(new String[]{"tem^requestDocument"}); 

dovrebbe fare il trucco.

Provatelo e fatemi sapere :)

3

può fare la logica di questo

importazioni

import org.dom4j.CDATA; 
import org.dom4j.DocumentHelper; 

codice di esempio

public static String appendCdata(String input) { 
    CDATA cdata = DocumentHelper.createCDATA(input);  
    return cdata.asXML(); 
} 
2
  1. È necessario creare una classe adattatore personalizzata che estende XMLAdapter classe.

importazione javax.xml.bind.annotation.adapters.XmlAdapter;

public class CDATAAdapter estende XMLAdapter {

@Override 
public String marshal(String inStr) throws Exception { 
    return "<![CDATA[" + inStr + "]]>"; 
} 

@Override 
public String unmarshal(String v) throws Exception { 
    return inStr; 
} 

}

  1. Dentro il tuo Java Bean o POJO definiscono XMLJavaTypeAdapter sulla stringa richiesta in CDATA

    @XmlJavaTypeAdapter (value = CDATAAdapter.class) messaggio String privato;

  2. Per impostazione predefinita, l'implementazione del marshaller dell'IR JAXB tenta di sfuggire ai caratteri. Per modificare questo comportamento, scriviamo una classe che implementa CharacterEscapeHandler.

Questa interfaccia ha un metodo di escape che deve essere sovrascritto.

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

m.setProperty("com.sun.xml.internal.bind.characterEscapeHandler", 
       new CharacterEscapeHandler() { 
        @Override 
        public void escape(char[] ch, int start, int length, 
          boolean isAttVal, Writer writer) 
          throws IOException { 
         writer.write(ch, start, length); 
        } 
       }); 

In secondo luogo, si può fare anche tramite l'implementazione di Eclipse MOXy.

0

Il server si aspetta <tem:requestDocument> per contenere il testo , e non un elemento <Request>. CDATA è davvero utile solo per la creazione di XML scritto a mano in modo da non doversi preoccupare di eseguire l'escape di XML incorporato. Il fatto è, JAXB gestisce l'escape in modo corretto e se il tuo server è un buon cittadino XML dovrebbe trattare correttamente XML di escape uguale a XML in un blocco CDATA.

Così, invece di aggiungere un richiesta elemento all'interno del vostro requestDocument come si fa in:

requestDocument = objFact.createRequestDocument(); 
request = new RequestDocument.Request(); 

... 
requestDocument.setRequest(request); 

Si dovrebbe prima utilizzare JAXB al maresciallo richiesta in un correttamente sfuggito String e impostare che sa il requestDocument valore:

requestDocument = objFact.createRequestDocument(); 
request = new RequestDocument.Request(); 

... 
String escapedRequest = marshal(request); 
requestDocument.setRequest(escapedRequest); 

L'esecuzione di marshal(request) viene lasciata come esercizio. ;)