Jaxb Marshalling Unmarshalling with Cdata

JAXB Marshalling Unmarshalling with CDATA

You could do the following:

AdapterCDATA

package forum14193944;

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

public class AdapterCDATA extends XmlAdapter<String, String> {

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

}

Root

The @XmlJavaTypeAdapter annotation is used to specify that the XmlAdapter should be used.

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;

}

Demo

I had to wrap System.out in an OutputStreamWriter to get the desired effect. Also note that setting a CharacterEscapeHandler means that it is responsible for all escape handling for that 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/Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<name><![CDATA[<h1>kshitij</h1>]]></name>
<surname><![CDATA[<h1>solanki</h1>]]></surname>
<id><![CDATA[0]]></id>
</root>

JAXB unmarshalling CDATA with HTML tags

A CDATA section starts with <![CDATA[ and ends with ]]>, so your XML document should become:

<rep>
<text type="full"><![CDATA[Demo, <a href="http://www.google.com" target="_blank">Search</a> thank you]]></text>
</rep>

Example Code

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

public class Example {

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

Unmarshaller unmarshaller = jc.createUnmarshaller();
File xsr = new File("src/forum16684040/input.xml");
Demo demo = (Demo) unmarshaller.unmarshal(xsr);

System.out.println(demo);
}

}

Output

[text=Demo, <a href="http://www.google.com" target="_blank">Search</a> thank you]

UPDATE

thanks, But this case i can't able to edit the XML, bcoz i get XML
from third party API. is there any way to get the result, which i
except.

You can use @XmlAnyElement and specify a DomHandler to keep the DOM content as a String. Below is a link to an answer that contains a full example:

  • JAXB use String as it is

Using custom CharacterEscapeHandler with JaxWsProxyFactoryBean to suppress CDATA being encoded

While we still could not find any documentation or example online through lots of debugging and reverse-engineering we managed to find a solution.

It is possible to provide custom marshaller properties into the JaxWsProxyFactoryBean that are used during creation of the internal Marshaller instance.

Those properties can be provided as part of a JAXBDataBinding to the factory.

A created instance of the custom CharacterEscapeHandler has to be put into the marshaller property "com.sun.xml.bind.characterEscapeHandler" (or "com.sun.xml.bind.marshaller.CharacterEscapeHandler" is also valid) of the JAXBDataBinding and then these will be respected by the factory.

...
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
LogHandler.configureFactory(factory);
factory.setServiceClass(PaymentCheck.class);
factory.setAddress(serviceUrl);
factory.setUsername(username);
factory.setPassword(password);

JAXBDataBinding jaxbDataBinding = new JAXBDataBinding();
Map<String, Object> marshallerProperties = new HashMap<>();
marshallerProperties.put("com.sun.xml.bind.characterEscapeHandler", new CdataCharacterEscapeHandler());
jaxbDataBinding.setMarshallerProperties(marshallerProperties);
factory.setDataBinding(jaxbDataBinding);

Check checkProxy = (Check)factory.create();

CheckResult = checkProxy.check(paramA, paramB);
...

Using this solution the JAX-WS proxy client created by the JaxWsProxyFactoryBean finally sends over the proper request to the server.

<data><![CDATA[<?xml version=....
<CheckData>
...
</CheckData>
]]></data>


Related Topics



Leave a reply



Submit