How can I specify JAXB customizations externally to a WSDL file?
Asked Answered
P

1

6

I have a WSDL file for a service implemented in .NET. I also have the same file with some "customizations" made by a 3rd-party to make the file tolerable to wsimport, mostly of the form:

<s:annotation>
  <s:appinfo>
    <jaxb:property name="result"/>
  </s:appinfo>
</s:annotation>

I'd like to be able to process the original WSDL from the vendor plus these overrides, but I'd like to specify them externally. I see that I can use the -b option for wsimport for "binding files" and I've tried to write an override file that currently looks like this:

<jxb:bindings version="1.0"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings node="//xs:element[@name='MyElementResult']">
    <jxb:property name="result"/>
  </jxb:bindings>
</jxb:bindings>

I've verified that "MyElementName" does in fact exist, in an element found here:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
     xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
     xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
     xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
     xmlns:tns="vendor-uri"
     xmlns:s="http://www.w3.org/2001/XMLSchema"
     xmlns:s2="http://microsoft.com/wsdl/types/"
     xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
     xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
     targetNamespace="vendor-namespace"
     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

  [...]
  <s:element name="MyElementResponse">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="MyElementResult" type="tns:Result" />

I'm getting this warning (and therefore no changes) from wsimport:

[ERROR] XPath evaluation of "//xs:element[@name='MyElementResult']" results in empty target node
  line 4 of file:/Users/..../wsdl/custom-bindings.xjb

Am I missing something in my declaration(s)? Do I have my XPath expression incorrect? If I get my XPath/overrides working, is it formatted correctly in order to achieve the same result as if I had edited the original WSDL?

Is this even possible using external files, or will I have to re-modify any future versions of the WSDL with these same changes?

Perpend answered 13/9, 2013 at 14:54 Comment(5)
Does it make a difference if you use the same namespace alias s in your override file as the original WSDL file has for the namespace http://www.w3.org/2001/XMLSchema, instead of the alias xs that you have above?Leningrad
Nope: when I use xmlns:s and then //s:element in the selector, I get the same error. I was kind of hoping that wsimport was just stupid and this would be the solution, but fortunately wsimport appears to treat XML properly and not worry when two different documents use different namespace names (which is the whole point of namespaces).Perpend
If you change the XPath expression do you get any different results? For example, specifying an absolute path, different but sufficiently equivalent matching criteria, etc.Leningrad
Looks like no: I changed the XPath to simply //s:element and I get the same error: [ERROR] XPath evaluation of "//s:element" results in empty target nodePerpend
I'm thinking that maybe I should just pre-process the WSDL myself using XSLT instead of relying on wsimport to do it for me.Perpend
S
1

You need to give the schema location in your bindings XML file.

<jxb:bindings version="1.0"
     xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
     xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jxb:bindings 
         schemaLocation="PATH_TO_YOUR_WSDL#types?schema1"
         node="//xs:schema[@targetNamespace='SCHEMA_NAMESPACE']">
        <jxb:bindings node="//xs:element[@name='MyElementResult']">
            <jxb:property name="result"/>
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

The #types?schema1 after the WSDL file name will specify which schema in the WSDL you are binding, starting at 1.

Shawnshawna answered 10/11, 2015 at 2:5 Comment(4)
This doesn't seem to fix the problem, but I may have done it incorrectly. If my WSDL file is called foo.wsdl, do I just literally use <jxb:bindings schemaLocation="foo.wsdl#types?schema1"> or is it more nuanced than that? (Hang on... there are multiple schemas in the WSDL file.. perhaps I have to repeat all that stuff...).Perpend
I added the following to the example: node="//xs:schema[@targetNamespace='SCHEMA_NAMESPACE']". Make sure that the SCHEMA_NAMESPACE value you provide matches the targetNamespace attribute on the schema you are trying to select.Shawnshawna
I'm making progress, here. Just coming back to this after 2 years takes some time :)Perpend
just <jxb:bindings schemaLocation="PATH_TO_YOUR_WSDL"> should be sufficient as your first bindings node.Skijoring

© 2022 - 2024 — McMap. All rights reserved.