How do you properly unmarshall an SOAP string with XML namespaces? - go

I'm having a hard time figuring out how to correctly and safely unmarshall a SOAP response with the following shape:
<xml>
<soap-env:Envelope
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header></soap-env:Header>
<soap-env:Body>
<n0:ZcustomerMasterInfoResponse
xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
<EOutput>
...Additional tags
</EOutput>
<n0:ZcustomerMasterInfoResponse/>
</soap-env:Body />
</soap:Envelop />
</xml>
This would be trivial with basic tags but there's quite a few namespaces such as soap-env, n0 etc. that are making it more complex to parse.

Related

SOAP Fault unexpected element but looks same

I am receiving this error. I have seen this answered several time but in those quesitons there was a wrogn name or case issue. This they look the same.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header />
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">unexpected element (uri:"http://service.xxx.com/provider/aaa/bbb/2015/", local:"retrieveAccountRequest"). Expected elements are <{http://service.xxx.com/provider/aaa/bbb/2015/}tns:retrieveAccountRequest></faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I did not notice the "tns:" on the expected elements. It is always the stupid, careless stuff that gets you.

Consuming XML response from a REST call in Spring Integration

Seems to be a simple task but I cannot get my head around it.
I have a Spring integration chain which calls an external Webservice, which returns an XML. I would like to use that XML response in a downstream XpathRouter.
What expected-response-type should I use?
<int:chain input-channel="filesChannel">
<!-- ... some previous components in the chain -->
<int-http:outbound-gateway
http-method="POST"
url="http://web/service/url"
expected-response-type="java.lang.String" />
<int-xml:xpath-router default-output-channel="resultChannel">
<int-xml:xpath-expression expression="/order/status" />
<int-xml:mapping value="Error" channel="importErrorChannel" />
</int-xml:xpath-router>
</int:chain>
It doesn't seem like the xpath-router can consume the XML returned by the webservice. When I debug the router with a breakpoint on the following line:
Node node = this.converter.convertToNode(message.getPayload());
The node is null, although the message does contain valid XML.
Is it because I am not setting the right expected-response-type?
Here is the response XML I receive from the service:
<apiResponse version="1.0">
<orders>
<order>
<orderReference>test_2_3045342</orderReference>
<status>Error</status>
<errors>
<error>
<errorCode>1100</errorCode>
<errorMessage><![CDATA[ "Field is required: dropWindow" ]]></errorMessage>
</error>
</errors>
</order>
</orders>
</apiResponse>
Ok, I found my mistake - it was actually in the XPATH expression. It should have been //order/status to enable deep search.
The java.lang.String expected-response-type works just fine with XML XpathRouter.
Thanks

Xpath not working in camel route

I'm sending soap xml through exchange object.When i try to route the request using xpath in apache camel,i'm not able to execute it properly.Please suggest
My Exchange body xml is
<Envelope><Header>
</Header>
<Body>
<Choice>
<Selector>1</selector>
</Choice>
</Body>
</Envelope>
My Camel Route
from(direct:XX)
.to(when(xpath("body()/Choice/Selector/.",String.class)=='1')
.to("direct:X")
.otherwise()
.to("direct:Y")
your Envelope cannot look like that. it must be something like:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
...
body()/Choice/Selector/. is not an Xpath. there is no such thing like body() in XPath.
Assuming that you have a SOAP Body content in the Exchange.body processed by some JAX-WS endpoint XPath will be
/Choice/Selector or /Choice/Selector/text() if it is an element with mixed content
BTW: if your Envelope is real example you try to test do not forget to fix your XML - you have wrong <Selector>1</selector> Tag names are case sensitive. It must be <Selector>1</Selector>

Validate XML against 2 XSD

I'm trying to parse and validate a SOAP request with SAX. Two XSD are necessary, one for SOAP envelope (http://schemas.xmlsoap.org/soap/envelope/) and the one I defined. I cannot find a way to properly validate the request against these two XSD.
Here's the code I use to parse the request and validate it against soapenv.xsd. It works fine. If I specify my XSD instead, the validation fails with "Cannot find the declaration of element 'soapenv:Envelope'".
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
SAXParser saxParser = factory.newSAXParser();
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", MyClass.class.getResourceAsStream("/xml/soapenv.xsd"));
InputSource is = new InputSource(MyClass.class.getResourceAsStream("/xml/request.xml"));
XMLReader reader = saxParser.getXMLReader();
reader.setContentHandler(new MyHandler());
reader.setErrorHandler(new MyErrorHandler());
reader.parse(is);
How can I specify a second XSD?
Is there a better way to parse and validate SOAP requests?
EDIT
As proposed, I created thirdpty.xsd that imports my two XSDs.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="thirdparty:general"
xmlns="thirdparty:general"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="D:\ucfed\ValidateWSDL\src\xml\soapenv.xsd"
namespace="http://schemas.xmlsoap.org/soap/envelope/"/>
<xs:import schemaLocation="D:\ucfed\ValidateWSDL\src\xml\Presence.xsd"
namespace="thirdparty:presence"/>
</xs:schema>
I specify this new XSD for the validation:
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", MyClass.class.getResourceAsStream("/xml/thidpty.xsd"));
But still, only the SOAP envelope XSD is used for validation. If a modify one element from my other XSD, the validation does not detect it.
Here is the xml I am trying to validate
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="thirdparty:presence">
<soapenv:Header/>
<soapenv:Body>
<urn:getPresenceQuery>
<urn:origAccount uri="test#origin.com"/>
<urn:destAccount uri="test#destination.com"/>
</urn:getPresenceQuery>
</soapenv:Body>
</soapenv:Envelope>
Other ideas ?
Write a driver schema document which imports the other two; validate against the driver.

Deserialize/Pulling a Spring's RestTemplate response from Atom source

I'm trying to use Spring's RestTemplate to get a response from an atom source. Is there a way to easily pull values from the response or deserialize it?
The response:
<?xml version='1.0' encoding='UTF-8'?>
<entry xmlns='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<id>https://apps-apis.google.com/a/feeds/domain/2.0/blah/verification/mx</id>
<updated>2013-03-19T19:47:02.805Z</updated>
<apps:property name='verified' value='false'/>
</entry>
Parse the feed with Abdera or ROME. They have nice representations of Atom feeds and feed entries with all their composing types.

Resources