Saltar al contenido

Desagrupamiento de Marshalling JAXB con CDATA

Este dilema se puede abordar de diversas formas, sin embargo te mostramos la que para nosotros es la respuesta más completa.

Solución:

Podrías hacer lo siguiente:

AdaptadorCDATA

package forum14193944;

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

public class AdapterCDATA extends XmlAdapter 

    @Override
    public String marshal(String arg0) throws Exception 
        return "

Raíz

los @XmlJavaTypeAdapter La anotación se utiliza para especificar que el XmlAdapter debería ser usado.

package forum14193944;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root 

    @XmlJavaTypeAdapter(AdapterCDATA.class)
    private String name;

    @XmlJavaTypeAdapter(AdapterCDATA.class)
    private String surname;

    @XmlJavaTypeAdapter(AdapterCDATA.class)
    private String id;


Manifestación

Tuve que envolver System.out en un OutputStreamWriter para obtener el efecto deseado. También tenga en cuenta que establecer un CharacterEscapeHandler significa que es responsable de todo el manejo de escape para ese Marshaller.

package forum14193944;

import java.io.*;
import javax.xml.bind.*;
import com.sun.xml.bind.marshaller.*;

public class Demo 

    public static void main(String[] args) throws Exception 
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum14193944/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(CharacterEscapeHandler.class.getName(),
                new CharacterEscapeHandler() 
                    @Override
                    public void escape(char[] ac, int i, int j, boolean flag,
                            Writer writer) throws IOException 
                        writer.write(ac, i, j);
                    
                );
        marshaller.marshal(root, new OutputStreamWriter(System.out));
    


input.xml / Salida



    kshitij]]>
    solanki]]>
    

Tenga en cuenta: Soy el EclipseLink JAXB (MOXy) líder y miembro de la JAXB (JSR-222) grupo de expertos.

Si usa MOXy como su proveedor JAXB (JSR-222), puede aprovechar la @XmlCDATA extensión para su caso de uso.

Raíz

los @XmlCDATA La anotación se usa para indicar que desea que el contenido de un campo / propiedad esté envuelto en una sección CDATA. los @XmlCDATA la anotación se puede utilizar en combinación con @XmlElement.

package forum14193944;

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

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root 

    @XmlCDATA
    private String name;

    @XmlCDATA
    private String surname;

    @XmlCDATA
    private String id;


jaxb.properties

Para usar MOXy como su proveedor JAXB, debe agregar un archivo llamado jaxb.properties con la siguiente entrada.

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Manifestación

A continuación se muestra un código de demostración para demostrar que todo funciona.

package forum14193944;

import java.io.File;
import javax.xml.bind.*;

public class Demo 

    public static void main(String[] args) throws Exception 
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum14193944/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    


input.xml / Salida

A continuación se muestra la entrada y la salida de la ejecución del código de demostración.



   kshitij]]>
   solanki]]>
   

Para más información

  • http://blog.bdoughan.com/2010/07/cdata-cdata-run-run-data-run.html
  • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html

Perdón por desenterrar esta pregunta y publicar una nueva respuesta (mi representante aún no es lo suficientemente alto como para comentar …). Me encontré con el mismo problema, probé la respuesta de Blaise Doughan, pero de mis pruebas, o no cubre todos los casos, o estoy haciendo algo mal en alguna parte.



    marshaller.setProperty(CharacterEscapeHandler.class.getName(),
                    new CharacterEscapeHandler() 
                        @Override
                        public void escape(char[] ac, int i, int j, boolean flag,
                                Writer writer) throws IOException 
                            writer.write(ac, i, j);
                        
                    );

De mis pruebas, este código elimina todos los escapes, sin importar si está utilizando el @XmlJavaTypeAdapter(AdapterCDATA.class) anotación en tu attribute…

Para solucionar ese problema, implementé lo siguiente CharacterEscapeHandler :

    public class CDataAwareUtfEncodedXmlCharacterEscapeHandler implements CharacterEscapeHandler 

        private static final char[] cDataPrefix = " cDataPrefix.length + cDataSuffix.length;
            if (isCData) 
                for (int i = 0, j = start; i < cDataPrefix.length; ++i, ++j) 
                    if (cDataPrefix[i] != ch[j]) 
                        isCData = false;
                        break;
                    
                
                if (isCData) 
                    for (int i = cDataSuffix.length - 1, j = start + length - 1; i >= 0; --i, --j) 
                        if (cDataSuffix[i] != ch[j]) 
                            isCData = false;
                            break;
                        
                    
                
            
            if (isCData) 
                out.write(ch, start, length);
             else 
                MinimumEscapeHandler.theInstance.escape(ch, start, length, isAttVal, out);
            
        
    

Si su codificación no es UTF *, es posible que no desee llamar a MinimumEscapeHandler sino a NioEscapeHandler o incluso a DumbEscapeHandler.

Comentarios y puntuaciones del tutorial

Nos encantaría que puedieras compartir esta reseña si te fue útil.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *