Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically extracting inline XSD from WSDL into XSD file(s)

I am using a third party Web Service whose definition and implementation are beyond my control. This web service will change in the future.

The Web Service should be used to generate an XML file which contains some of the same data (represented by the same XSD types) as the Web Service plus some extra information generated by the program.

My approach:

  1. create my own XSD referring to the XSD definitions of the WSDL of the called web service (This XSD also includes XSD types for the extra information obviously.)
  2. use a Java XML databinding framework (like ADB or JiXB) to generate the databinding classes from my own XSD file from step 1
  3. use a Java SOAP framework (like Axis2 or CXF) with the same databinding framework to generate the databinding classes from the WSDL (This would enable me to use the objects retrieved by the web service directly in the generation of the XML.)

The XSD types I am going to use in my own XSD file, but are defined in the WSDL, are subject to change. Whenever they change, I would like to automatically process the XSD and WSDL databinding again. (If the change is significant enough, this might trigger some development effort.(But usually not.))

My problem:

In step 1 I need an XSD referring to the same types as used by the Web Service.

The WSDL is referring to another WSDL, which is referring to another WSDL etc. Eventually there is an WSDL with the needed inline XSD types. As far as I know there is no way to directly reference the inline XSD types of a WSDL from an XSD.

The approach I would think most viable, is to include an extra step in the automatic processing (before the databinding) that extracts the inline XSD from the WSDL into other XSD file(s). These other XSD file(s) can then be referred to by my own XSD file.

Things I'd like to avoid:

  • Manually copy pasting the inline XSD into an XSD file (I am looking for an automatic process.)
  • Any manual steps.(Like the determining the WSDL that contains the inline types manually.(The location of that WSDL does change as well.))
  • Using xsd:any in my own XSD. I would like my own XSD file to be correct.
  • Using a non-Java technology(like .NET)
  • Huge amounts of implementation (but hints on how you would implement such an extraction are welcome anyway)

PS: I found some similar questions, but they all had responses like: WTH would you want to do that? That is the reason for my rather large background story.

like image 310
Steven Geens Avatar asked Mar 26 '10 03:03

Steven Geens


2 Answers

I don't know any libraries that would do this for you, but it is definitly possible to implement with a bit of effort (~200 lines). A rough meta-program to generate all inline and included XSDs:

method processWSDL(Document wsdl) {
    for each ("/wsdl:definitions/wsdl:types/xsd:schema" in wsdl) {
        call processXSD("inline_[i].xsd",".")
    }
    for each ("/wsdl:definitions/wsdl:import" in wsdl) {
        Document x = read and parse ("@location")
        if (x is WSDL) call processWSDL(x)
        else if (x is XSD) call processXSD("@location", x)
    }
}

method processXSD(String filename, Document xsd) {
    write "xsd" to a new file "filename"   // if 'filename' is a URL, take only the part after the last '/'
    for each ("/xsd:schema/xsd:import" or "/xsd:schema/xsd:include" in xsd) {
        if ("@schemaLocation" is local reference) {     // no 'http://' prefix
            Document x = read and parse ("@schemaLocation")
            call processXSD("@schemaLocation", x)
        }
    }
}

It is not a full solution, e.g. does not handle namespace prefixes defined outside of the inline schema, but hopefully gives a good starting point.

like image 168
Miklos Csuka Avatar answered Oct 18 '22 10:10

Miklos Csuka


Just to keep this post relevant, things have changed since an answer was accepted. It is now possible in Java to generate what you want starting from WSDL; JAX-WS provides the wsimport tool that does exactly what's requested: take the WSDL, create a client proxy along with a bunch of JAXB-annotated classes for un/marshalling of requests.

I would say though, to @MoizTankiwala 's point, that the need to export XSD content from WSDL (or to include all external XSD content inside a WSDL's types section) is alive and well.

The former is something that makes sense when someone has a large body of XSDs, and there's a general concern regarding effective managing, analysing and evolving of that model in XSD.

The latter is also sought after since some (mainly) dynamic languages still lack full blown support from tooling when it comes to WSDL to client side proxy generation.

My other answer on SO talks about a similar need, that should help at least with Moiz's request...

like image 36
Petru Gardea Avatar answered Oct 18 '22 08:10

Petru Gardea