yogsma
yogsma

Reputation: 10584

XPath evaluation of results in an empty target node

My wsdl specification contains imported XSD schema.

wsdl file looks like below

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ....>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd2" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svcc?xsd=xsd4" namespace="http://schemas.datacontract.org/2004/07/System.Web.Services.Protocols"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd0" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd1" namespace="http://schemas.datacontract.org/2004/07/ABCUser.Web.Services"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/ABCUser.Web.ServiceModels"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd5" namespace="http://schemas.datacontract.org/2004/07/System"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd6" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd7" namespace="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd8" namespace="http://schemas.datacontract.org/2004/07/ABC.Fs.UIEntities"/>
<xsd:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd9"/>
</xsd:schema>
</wsdl:types>
 .......
 </wsdl:definitions>

My jaxb bindings file look like below:

<jaxws:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1"
    wsdlLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?wsdl">
    <enableWrapperStyle>true</enableWrapperStyle>
    <enableAsyncMapping>false</enableAsyncMapping>
    <jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema/xs:complexType[@name='Node']/xs:sequence/xs:element[@name='Type']">
    <jaxb:class name="NodeTypeString"/>
    </jaxws:bindings>    
</jaxws:bindings>

If I don't use bindings.xml, I get following error while generating java classes through wsimport

[ERROR] Two declarations cause a collision in the ObjectFactory class.
  line 1 of https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd3

[ERROR] (Related to above error) This is the other declaration.
  line 1 of https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd3

Schema it is complaining about looks like below

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/ABCUser.Web.ServiceModels" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/ABCUser.Web.ServiceModels">
<xs:import schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd6" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
.......
<xs:complexType name="Node">
<xs:sequence>
<xs:element minOccurs="0" name="Description" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Type" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="Users" nillable="true" type="tns:ArrayOfUser"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Node" nillable="true" type="tns:Node"/>
......

But now when I use bindings.xml, I get the following error

[ERROR] XPath evaluation of "wsdl:definitions/wsdl:types/xs:schema/xs:complexType[@name='Node']/xs:sequence/xs:element[@name='Type']" results in an empty target node
  line 8 of file:/E:/projects/codegeneration/bindings.xml

What am I missing? I am using wsimport to generate the classes.

Upvotes: 1

Views: 4819

Answers (2)

yogsma
yogsma

Reputation: 10584

I got two solutions for this issue I was facing.

  1. I streamlined the wsdl schema by adding imported schema in it and removing import statements.
  2. First build an episode using xjc for imported schema

    xjc -episode myschema.episode myschema.xsd

    And then use that episode as a binding in java classes generation through wsimport

    wsimport mywsdl.wsdl -b myschema.episode

More about 2nd solution here

Upvotes: 1

VGR
VGR

Reputation: 44404

<xsd:import> does not actually change the WSDL file’s XML document tree. You have elements matching wsdl:definitions/wsdl:types/xs:schema/xs:import, not wsdl:definitions/wsdl:types/xs:schema/xs:complexType/xs:sequence/xs:element.

The JAX-WS specification’s “Customizations” chapter says:

Additionally, jaxb:bindings MAY appear inside a JAX-WS external binding file as a child of a jaxws:bindings element whose node attribute points to a xs:schema element inside a WSDL document. When the schema is processed, the outcome MUST be as if the jaxb:bindings element was inlined inside the schema document as an annotation on the schema component.

While processing a JAXB binding declaration (i.e. a jaxb:bindings element) for a schema document embedded inside a WSDL document, all XPath expressions that appear inside it MUST be interpreted as if the containing xs:schema element was the root of a standalone schema document.

So, your inner jaxws:bindings element must contain the XPath of the xs:schema element, not any of its descendants:

<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema">
    <jaxb:bindings node="xs:complexType[@name='Node']/xs:sequence/xs:element[@name='Type']">
        <jaxb:class name="NodeTypeString"/>
    </jaxb:bindings>
</jaxws:bindings>    

I’m not sure if the above will actually work with a schema that uses <xsd:import>. You may have to refer to the imported schema explicitly:

<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema">
    <jaxb:bindings schemaLocation="https://abcserver.com/v2/two-way-ssl/MyService.svc?xsd=xsd2">
        <jaxb:bindings node="xs:complexType[@name='Node']/xs:sequence/xs:element[@name='Type']">
            <jaxb:class name="NodeTypeString"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxws:bindings>    

Upvotes: 2

Related Questions