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">
...