Hi, Your pointer was very helpful, however the fix was still extremely tricky. I have created a JIRA bug and attached a patch to it.
https://issues.apache.org/jira/browse/CAMEL-8663 The root cause behind all this hassle was that the ReadHeadersInterceptor (from CXF) reads part of the Stax stream and consumes the events that contain the namespace definitions. The rest of the XMLStreamReader (starting at the first payload element) is wrapped (and put into a new StaxSource) and ends up in the DefaultCxfBinding. At that point the namespaces are somewhat accessible, but there is no way to get all the namespaces already defined (for DOM this is possible and there is some special handling for that). I had to add another interceptor that wraps the initial XMLStreamTrader before the SOAP envelope is read, tracks the namespaces (and adds that tracker to the CXF Message object). The DefaultCxfBinding is then able to read this and wrap the XMLStreamReader again, so these namespaces get accessible again. This is not really nice, but I actually haven't found any better way to do that. What do you think? Best regards Stephan -----Original Message----- From: Willem Jiang [mailto:[email protected]] Sent: Mittwoch, 15. April 2015 17:43 To: [email protected] Subject: Re: Camel-CXF will generate invalid XML in some cases Hi Stephan, How did you turn the payload body into String? If you use the CxfPayload.getBody() you should get the a list of element which namespaces are set rightly. The PayLoadDataFormatFeature[1] just setup the interceptors for CXF to avoid processing the message part. I guess that is the missing pice that you want to know :) [1]https://github.com/apache/camel/blob/master/components/camel-cxf/src/main/java/org/apache/camel/component/cxf/feature/PayLoadDataFormatFeature.java -- Willem Jiang Red Hat, Inc. Web: http://www.redhat.com Blog: http://willemjiang.blogspot.com (English) http://jnn.iteye.com (Chinese) Twitter: willemjiang Weibo: 姜宁willem On April 15, 2015 at 10:21:38 PM, Siano, Stephan ([email protected]) wrote: > Hi, > > I am currently trying to debug an issue that is actually driving me crazy. I > am calling > a web service from a camel cxf endpoint in payload mode that returns data > that uses a namespace > in an attribute name that is defined on the SOAP envelope of the response. If > I convert > the CxfPayload into a String, the XML will be invalid because the namespace > definition > is missing. > > The response message looks like this: > > > > > > > xsi:type="xsd:string">ResponseData > > If you try any XML operation on this (like an XPath) the parser will complain > that the xsi > namespace prefix is undefined. > > The route looks like that: > > > > > > > > and the endpoint is defined like that: > > address="http://localhost:8080/cxf/getSeedDummyService" > endpointName="orange:MessageFlow_2" > id="SII_SEED_SII_GET_SEED"> > > > > > > > My analysis so far is that the Source that is transferred from a CXF Message > object to a > Camel CxfPayload object is a StaxSource (the CXF class). If I try similar > things in Camel-CXF > unit tests, the source seems to be a DOMSource for some reason (and there is > some special > code for namespace handling in DefaultCxfBinding for that). > > However I have not managed to figure out where the SOAP envelop is read in > payload mode > and how to get a proper transformation in to anything flat that does not lose > the namespace > but does not parse the whole thing into a DOM tree (which is pretty huge). It > am also under > the impression that Woodstox does also play some role in this context (the > XMLStreamReader > behind the StaxSource is from Woodstox and this does not return these outer > namespaces > with the getNamespaceCount() method. > > Does anybody have an idea how to proceed here? > > Best regards > Stephan >
