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
>  

Reply via email to