The problem is that the inline schema definitions in core.wsdl and search.wsdl do not have namespace defined for the target namespace (to which all defined elements belong to). The target namespace indicates that the vocabulary defined in this inline schema (talking about core.wsdl now only for simplicity) belong to a namespace "http://api.kartoteka.ru/core/v3/"
. So when the already defined vocabulary (complexType Error
in this case) is referenced later on without any prefix it means that it should come from the default namespace. The default namespace is not defined in <xs:schema targetNamespace="http://api.kartoteka.ru/core/v3/">
, but it should be taken from:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://api.kartoteka.ru/core/v3/" targetNamespace="http://api.kartoteka.ru/core/v3/">
Because as stated in the XML names spec, section 6.2, it should be inherited :
The scope of a default namespace declaration extends from the
beginning of the start-tag in which it appears to the end of the
corresponding end-tag, excluding the scope of any inner default
namespace declarations. In the case of an empty tag, the scope is the
tag itself.
A default namespace declaration applies to all unprefixed element
names within its scope. Default namespace declarations do not apply
directly to attribute names; the interpretation of unprefixed
attributes is determined by the element on which they appear.
If there is a default namespace declaration in scope, the expanded
name corresponding to an unprefixed element name has the URI of the
default namespace as its namespace name. If there is no default
namespace declaration in scope, the namespace name has no value. The
namespace name for an unprefixed attribute name always has no value.
In all cases, the local name is local part (which is of course the
same as the unprefixed name itself).
I think that wsimport's behaviour is wrong as it does not take default namespace from the parent element. Adding default namespace is enough to "fix" this. So you only need to change one line for core.wsdl (line 8):
<xs:schema xmlns="http://api.kartoteka.ru/core/v3/" targetNamespace="http://api.kartoteka.ru/core/v3/">
and one line for search.wsdl (line 7):
<xs:schema xmlns="http://api.kartoteka.ru/search/v3/" targetNamespace="http://api.kartoteka.ru/search/v3/" elementFormDefault="qualified">
I am leaving other workarounds (below) which I wrote earlier but they are more complex (compared to this one) and aren't actually needed.
Maybe the simplest one is to make necessary changes to use namespaces in the embedded schema definitions.
In search.wsdl make these changes (line 7 and line 26):
<xs:schema xmlns:tns="http://api.kartoteka.ru/search/v3/" targetNamespace="http://api.kartoteka.ru/search/v3/" elementFormDefault="qualified">
and
<xs:element name="error" type="tns:Error"/>
In core.wsdl make similar changes (line 8 and lines 15-18):
<xs:schema xmlns:tns="http://api.kartoteka.ru/core/v3/" targetNamespace="http://api.kartoteka.ru/core/v3/">
and
<xs:element name="systemError" type="tns:Error" />
<xs:element name="serviceRestriction" type="tns:Error" />
<xs:element name="authorizationRestriction" type="tns:Error" />
Another way would be to define Error
complexType outside of the wsdl file and import it in your core.wsdl and search.wsdl files.
Create external schema file: common.xsd
with contents like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://mycustomschema/common/"
targetNamespace="http://mycustomschema/common/">
<xs:complexType name="Error">
<xs:sequence>
<xs:element name="code" type="xs:positiveInteger"/>
<xs:element name="msg" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Reference your custom complexType in search.wsdl:
<xs:import namespace="http://mycustomschema/common/" schemaLocation="common.xsd"/>
<xs:element name="sessionId" type="xs:string"/>
<xs:element xmlns:common="http://mycustomschema/common/" name="error" type="common:Error"/>
Reference your custom complexType in core.wsdl:
<xs:import namespace="http://mycustomschema/common/" schemaLocation="common.xsd"/>
<xs:element xmlns:common="http://mycustomschema/common/" name="systemError" type="common:Error" />
<xs:element xmlns:common="http://mycustomschema/common/" name="serviceRestriction" type="common:Error" />
<xs:element xmlns:common="http://mycustomschema/common/" name="authorizationRestriction" type="common:Error" />
One more method is to change element="error"
to type="Error"
:
Remove this line from search.wsdl:
<xs:element name="error" type="Error"/>
Change these lines in search.wsdl:
<wsdl:message name="SearchError">
<wsdl:part name="searchError" type="Error"/>
</wsdl:message>
<wsdl:message name="CardError">
<wsdl:part name="cardError" type="Error"/>
</wsdl:message>
<wsdl:message name="ImportantFactsError">
<wsdl:part name="importantFactsError" type="Error"/>
</wsdl:message>
<wsdl:message name="PledgeError">
<wsdl:part name="pledgeError" type="Error"/>
</wsdl:message>
<wsdl:message name="VocabularyError">
<wsdl:part name="vocabularyError" type="Error"/>
</wsdl:message>
<wsdl:message name="BoYearsRequest">
<wsdl:part name="request" type="bo:orgBoYearsRequest"/>
</wsdl:message>
<wsdl:message name="BoYearsResponse">
<wsdl:part name="response" type="bo:orgBoYearsResponse"/>
</wsdl:message>
<wsdl:message name="BoError">
<wsdl:part name="boError" type="Error"/>
</wsdl:message>
Remove these lines from search.wsdl:
<xs:element name="systemError" type="Error" />
<xs:element name="serviceRestriction" type="Error" />
<xs:element name="authorizationRestriction" type="Error" />
Change these lines in search.wsdl:
<wsdl:message name="SystemError">
<wsdl:part name="systemError" type="Error"/>
</wsdl:message>
<wsdl:message name="ServiceRestriction">
<wsdl:part name="serviceRestriction" type="Error"/>
</wsdl:message>
<wsdl:message name="AuthorizationRestriction">
<wsdl:part name="authorizationRestriction" type="Error"/>
</wsdl:message>
This way you can use the type defined in embedded schema definition directly and wsimport seems to understand the wsdl file this way.