apache axis xsi:type anonymous complex type .NET "No type definition found for the type referenced by the attribute 'xsi:type'"
Problem:
The schema definition for a response element may define the complex type "inline" rather than by reference. This is known as an "anonymous type". Eg:
<xs:element name="MyResponse"> <xs:annotation> <xs:documentation>This is the root element of the Response.</xs:documentation> </xs:annotation> <xs:complexType> <xs:sequence> <xs:element name="PropertyOne" type="xs:string" minOccurs="0"/> <xs:element name="PropertyTwo" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element>
When axis generates the SOAP response (with the default settings) this includes
xsi:type
attributes. Eg:<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<MyResponse xsi:type="ns1:MyResponse" xmlns="http://example.com/service" xmlns:ns1="http://example.com/service">
...
This is accepted by AXIS-generated client code but in .NET (and other schema-validating tools such as XMLSpy) you'll get an error along the lines of
No type definition found for the type referenced by the attribute 'xsi:type'='ns1:MyResponse' of element <MyResponse>
The error inidicates validation is probably doing the right thing with the
xsi:type
attribute and checking it - there is actually no type with this name, it's anonymous. Can the behavour in AXIS be changed?Solution:
Thankfully there is a configuration setting in AXIS to stop this output -
sendXsiTypes
, which is true
by default:<parameter name="sendXsiTypes" value="false"/>
There are a number of ways to get this setting in there. I'd recommend creating a wsdd deploy file for just the
globalConfiguration
and deploy this to the AXIS AdminServlet as you would do with the deploy.wsdd definitions for the other service(s). So an example
globalConfig-deploy.wsdd
:<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <globalConfiguration> ... <parameter name="sendXsiTypes" value="false" /> ... </globalConfiguration> </deployment>
You'll find the MyApp/WEB-INF/server-config.wsdd will then be updated and the SOAP excludes this attribute as advertised:
<?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <MyResponse xmlns="http://example.com/service"> ...
The alternative to this (if you do want the
xsi:type
attributes) is to define explicit types for your root response elements. Eg:<xs:element name="MyResponse" type="MyResponseType"> <xs:annotation> <xs:documentation>This is the root element of the Response.</xs:documentation> </xs:annotation> </xs:element> <xs:complexType name="MyResponseType"> <xs:annotation> <xs:documentation>This is the type for the root element of the Response.</xs:documentation> </xs:annotation> <xs:sequence> <xs:element name="PropertyOne" type="xs:string" minOccurs="0"/> <xs:element name="PropertyTwo" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType>
The XML from AXIS will then include
xsi:type
but the value will be correct - referencing a type that does exist. Eg:<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<MyResponse xsi:type="ns1:MyResponseType" xmlns="http://example.com/service" xmlns:ns1="http://example.com/service">
...
No comments:
Post a Comment