title: How to use xsd:any element to return xml as a string
body: <p>I need to replicate an old web service generated by and deployed on Oracle. The new service will be written in Java and deployed on Tomcat. All the functionality of the original service must be exactly the same, meaning that I cannot change either the wsdl or the format of the response object.</p>
  
  <p>I am using cxf and wsdl2java to generate the stubbed out classes and service. My problem is that the original wsdl makes use of the "any" element and the response has unusual xml code populated into that element. I can't seem to reproduce the same response as the original service.</p>
  
  <p>The request and response type definitions in the wsdl:</p>
  
  <pre><code>        &lt;complexType name="getNewServiceXML"&gt;
              &lt;sequence&gt;
                  &lt;element name="pNum" nillable="true" type="decimal" /&gt;
              &lt;/sequence&gt;
          &lt;/complexType&gt;
          &lt;complexType name="getNewServiceXMLResponse"&gt;
              &lt;sequence&gt;
                  &lt;element name="result" nillable="true"&gt;
                      &lt;complexType&gt;
                          &lt;sequence&gt;
                              &lt;any /&gt;
                          &lt;/sequence&gt;
                      &lt;/complexType&gt;
                  &lt;/element&gt;
              &lt;/sequence&gt;
          &lt;/complexType&gt;
  </code></pre>
  
  <p>CXF generates the GetNewServiceXMLResponse class, and within that class is the Result class. The any field is found in the Result.</p>
  
  <pre><code>@XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(name = "getNewServiceXMLResponse", propOrder = {
      "result"
  })
  public class GetNewServiceXMLResponse {
  
      @XmlElement(required = true, nillable = true)
      protected GetNewServiceXMLResponse.Result result;
  
  ...
  
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "", propOrder = {
          "any"
      })
      public static class Result {
  
          @XmlAnyElement(lax = true)
          protected Object any;
  ...
  </code></pre>
  
  <p>This is the expected response format:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://dev.mycompany.com/NewService.wsdl/types/"&gt;
    &lt;env:Body&gt;
      &lt;ns0:getNewServiceXMLResponseElement&gt;
          &lt;ns0:result&gt;
              &lt;result&gt;
                  &lt;ROWSET&gt;
                      &lt;ROW num="0"&gt;
                          &lt;FIELD1&gt;3649648&lt;/FIELD1&gt;
                          &lt;FIELD2&gt;WEEK&lt;/FIELD2&gt;
                          &lt;FIELD3&gt;TTN476273&lt;/FIELD3&gt;
                      &lt;/ROW&gt;
                      &lt;ROW num="1"&gt;
                          &lt;FIELD1&gt;3649650&lt;/FIELD1&gt;
                          &lt;FIELD2&gt;WEEK&lt;/FIELD2&gt;
                          &lt;FIELD3&gt;TTN476273&lt;/FIELD3&gt;
                      &lt;/ROW&gt;
                      &lt;ROW num="2"&gt;
                          &lt;FIELD1&gt;540969&lt;/FIELD1&gt;
                          &lt;FIELD2&gt;DAY&lt;/FIELD2&gt;
                          &lt;FIELD3&gt;null&lt;/FIELD3&gt;
                      &lt;/ROW&gt;
                  &lt;/ROWSET&gt;
              &lt;/result&gt;
          &lt;/ns0:result&gt;
      &lt;/ns0:getNewServiceXMLResponseElement&gt;
  &lt;/env:Body&gt;
  </code></pre>
  
  <p></p>
  
  <p>I'm getting hung up on the ROW num="X" tags. I have not seen that before in SOAP services. So I tried just creating the ROWSET xml by hand and putting it into a string. Then passed the string back through the any element. In order to get that to work, I wrapped it in a JAXBElement so it could unmarshall successfully.</p>
  
  <pre><code>List&lt;Object&gt; dataRecords = manager.getDataRecords(request.getPNum());
  GetNewServiceXMLResponse response = new GetNewServiceXMLResponse();
  String str = manager.convertDataToString(dataRecords);
  JAXBElement&lt;String&gt; obj = new JAXBElement&lt;String&gt;(new QName("result"), String.class, str);
  result.setAny(obj);
  response.setResult(result);
  </code></pre>
  
  <p>Now the problem with that approach is that the string gets encoded (since it's a string...) and you end up with the <code>&amp;lt; blah blah &amp;gt;</code> etc instead of the pretty xml.</p>
  
  <pre><code>&lt;getNewServiceXMLResponseElement xmlns="http://dev.mycompany.com/NewService.wsdl/types/"&gt;
    &lt;result&gt;
      &lt;result xmlns:ns2="http://dev.mycompany.com/NewService.wsdl/types/" xmlns=""&gt;&amp;lt;ROWSET&amp;gt;..snip..&amp;lt;/ROWSET&amp;gt;&lt;/result&gt;
    &lt;/result&gt;
  &lt;/getNewServiceXMLResponseElement&gt;
  </code></pre>
  
  <p>So next I tried creating a Document (as suggested by other posts)</p>
  
  <pre><code>DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  DocumentBuilder builder = factory.newDocumentBuilder();
  Document document = builder.parse(new InputSource(new StringReader(str)));
  JAXBElement&lt;Document&gt; obj = new JAXBElement&lt;Document&gt;(new QName("result"),Document.class,document);
  </code></pre>
  
  <p>This gets me an error:</p>
  
  <pre><code>WARNING: Interceptor has thrown exception, unwinding now
  org.apache.cxf.interceptor.Fault: Marshalling Error: org.w3c.dom.Document is not known to this context
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:159)
      at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:169)
      at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:105)
      at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
      at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:74)
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
      at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:104)
      at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:99)
      at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:452)
      at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:196)
      at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:220)
      at org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServlet.java:153)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
      at org.apache.cxf.transport.servlet.AbstractCXFServlet.service(AbstractCXFServlet.java:211)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
      at com.googlecode.psiprobe.Tomcat70AgentValve.invoke(Tomcat70AgentValve.java:38)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
      at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
      at java.lang.Thread.run(Thread.java:662)
  Caused by: javax.xml.bind.MarshalException
   - with linked exception:
  [javax.xml.bind.JAXBException: org.w3c.dom.Document is not known to this context]
      at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318)
      at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
      at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:75)
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.writeObject(JAXBEncoderDecoder.java:444)
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:138)
      ... 31 more
  Caused by: javax.xml.bind.JAXBException: org.w3c.dom.Document is not known to this context
      at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246)
      at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:144)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:189)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:315)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:322)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:72)
      at com.sun.xml.bind.v2.runtime.property.SingleReferenceNodeProperty.serializeBody(SingleReferenceNodeProperty.java:111)
      at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
      at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
      at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
      at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332)
      at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:699)
      at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:157)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:189)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:315)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:322)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:72)
      at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
      at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
      ... 35 more
  Caused by: javax.xml.bind.JAXBException: org.w3c.dom.Document is not known to this context
      at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:621)
      at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:141)
      ... 53 more
  </code></pre>
  
  <p>Now what? Am I going down the wrong path trying to send XML as something other than what it is (like a string)? Is there a way to better replicate the ROW num="X" behaviour? Without the ability to change the wsdl (and hence the underlying objects), I haven't come up with an answer.</p>
  
  <p>Additional info: Tomcat 7, Java 1.6</p>