I'm trying to turn a WSDL file into Java code using wsimport
by running this command (which should work from anyone's machine):
wsimport https://webservices-uatprod.dhisco.com/OTAHotelDescriptiveInfo/web_services?WSDL -J-Djavax.xml.accessExternalDTD=all -J-Djavax.xml.accessExternalSchema=all -B-XautoNameResolution -Xnocompile
However, I keep getting this error:
[ERROR] 'lang' is already defined
line 93 of http://www.w3.org/2001/03/xml.xsd
[ERROR] (related to above error) the first definition appears here
line 43 of http://www.w3.org/2001/xml.xsd
[ERROR] 'space' is already defined
line 102 of http://www.w3.org/2001/03/xml.xsd
[ERROR] (related to above error) the first definition appears here
line 89 of http://www.w3.org/2001/xml.xsd
[ERROR] 'base' is already defined
line 109 of http://www.w3.org/2001/03/xml.xsd
[ERROR] (related to above error) the first definition appears here
line 113 of http://www.w3.org/2001/xml.xsd
[ERROR] 'specialAttrs' is already defined
line 117 of http://www.w3.org/2001/03/xml.xsd
[ERROR] (related to above error) the first definition appears here
line 157 of http://www.w3.org/2001/xml.xsd
I've spent hours googling this to try and find the solution. I'm relatively convinced I need to specify a binding file with the -b binding.xml
flag.
However, I'm having a very hard time figuring out how to create that binding file. Here's what I've attempted:
binding.xml
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3c.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/03/xml.xsd"
jaxb:version="2.0">
<jaxb:bindings schemaLocation="http://www.w3.org/2001/xml.xsd">
<jaxb:bindings node="//xs:attribute[@name='lang']">
<jaxb:property name="langAttribute"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
Then with this in place, I try running with the binding file by:
wsimport https://webservices-uatprod.dhisco.com/OTAHotelDescriptiveInfo/web_services?WSDL -J-Djavax.xml.accessExternalDTD=all -J-Djavax.xml.accessExternalSchema=all -B-XautoNameResolution -Xnocompile -b binding.xml
And now I get:
[ERROR] XPath evaluation of "//xs:attribute[@name='lang']" results in empty target node
line 6 of file:/Users/name/git/foo/bar/src/main/resources/wsdl/binding.xml
I've tried many other combinations of the binding file's XPath... I figure I need to rename the attribute of all elements from 'lang' to something else, but I really have been having a hard time figuring it out.
Thanks in advance for any help!
Solution Update:
I got past this error by downloading the schemas locally, and wherever there was a reference to schemaLocation="http://www.w3.org/2001/03/xml.xsd"
and schemaLocation="http://www.w3.org/2001/xml.xsd"
, I edited the XML to point to my local copy of the file on the file system.
I.e. opened up each *.xsd file where there was reference to these files, and updated each line from something like this:
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
To this:
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="./xml.xsd"/>
After that, it was able to generate the Java classes using the wsimport
syntax above (did require one small binding file, but that was related to an vendor-defined class).
You've bound your xs
prefix to the XML namespace http://www.w3.org/2001/03/xml.xsd
, but it should be bound to the XML Schema namespace http://www.w3.org/2001/XMLSchema
:
xmlns:xs="http://www.w3.org/2001/XMLSchema"
Another problem you'll face is that your schema seem to address xml.xsd
via two different locations: http://www.w3.org/2001/xml.xsd
and http://www.w3.org/2001/03/xml.xsd
. That will get you a lot fo duplicates. You can try to resolve them via catalogs like:
REWRITE_SYSTEM "http://www.w3.org/2001/03/" "http://www.w3.org/2001/"
(And the use it with -catalog
.)
But I'm not sure this will work. In a similar situation I've created a full local copy of schemas I needed to compile and patched them to use uniform schema locations.
I tried downloading the schemas and xml files locally, but am not sure how to tell wsimport to look for the local copies instead of going out to the internet. If I have a copy of xsd.xml locally... is there a way to tell wsimport to use that instead of any it may find on the internet?
I'm not exactly sure about wsimport
but generally it is done with catalogs. Assume you've downloaded schemas from http://www.w3.org
in the directory w3c
. Then you'll have a catalog file like
REWRITE_SYSTEM "http://www.w3.org/" "w3c/"
Then you should be able to use this catalog file via wsimport -catalog mycatalog.cat ...
. wsimport
or underlying schema compiler xjc
should get your http://www.w3.org/2001/xml.xsd
schema from w3c/2001/xml.xsd
then.
However, I've never tried it with wsimport
, I just routinely use it with maven-jaxb2-plugin
.