tags:

views:

265

answers:

2

Hi there,

I've inherited a project which uses JAXB heavily to map XML messages onto Java objects. The problem I have is that some of the data which I receive (in this case nested XML of unknown form) has NOT to be unmarshalled, rather captured as a String.

An example will help

<a>
   <b></b>
   <c></c>
   <d>
       <!-- "Unknown" XML here -->
       <maybeE></maybeE>
       <maybeF></maybeF>
       <!-- etc etc -->
   <d/>
</a>

So I would want the JAXB to unmarshall "b" and "c" but "d" it would capture the nested XML as a string i.e. not parsed.

So calling:

getD()

Would return string:

"<maybeE></maybeE><maybeF></maybeF>"
+3  A: 

You can't capture the nested content as a String, but you can capture it as a DOM, e.g.

@XmlRootElement(name="a")
public class A {

   @XmlElement
   private String b;

   @XmlElement
   private String c;

   @XmlAnyElement
   private List<Element> content;
}

Whatever <a> contains, which does not match <b> or <c>, will be stored under content. You can then convert those Element objects into Strings, if you so wish.

skaffman
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptionsorg.w3c.dom.Element is an interface, and JAXB can't handle interfaces.
Lawrence Tierney
@Lawrence: Oops, my bad. Fixed.
skaffman
Thank you - that worked perfectly
Lawrence Tierney
@Lawrence: Glad I could help. This is where you click the tick symbol next to my answer :)
skaffman
"Tick" - haha - sorry. done
Lawrence Tierney
+1  A: 

I found the above very useful; I had a similar mapping issue where I had HTML which was not escaped or encoded stored in an xml file - and I wanted to map this to a String property.

I used the annotation:

@XmlElementWrapper(name="operations")
@XmlAnyElement
private List<Node> operations;

Then used a transformer to print the node tree:

public String getOperationsAsString() throws Exception{
    StringBuilder builder = new StringBuilder();
    for (Node node: operations) {
        StringWriter writer = new StringWriter();
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.transform(new DOMSource(node), new StreamResult(writer));
        builder.append(writer.toString());
    }
    return builder.toString();
}
Andrew B