Announcement Announcement Module
Collapse
No announcement yet.
Idea for new XSD to WSDL generator Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Idea for new XSD to WSDL generator

    Reading through the forum and through the JIRA issues, I see that a lot of people have issues with XSD includes and imports while using the XsdBasedSoap11Wsdl4jDefinitionBuilder.

    The current workaround is to store the external schemas in the WAR file, and make sure that requests for these are not mapped in the web.xml. See http://forum.spring.io/node/42089, for instance. However, this workaround is a bit complex, and causes problems for a lot of people. Additionally, some SOAP clients don't follow the links to these external schema's, which causes even more issues.

    I've been thinking about a new way to do this. Basically, the idea is to inline all included XSDs into the including XSD, and inline all imported XSDs into the WSDL. Here's an example. It's a bit complex, but it tackles all cases. The main schema is the following, called A.xsd:

    Code:
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="urn:1"
                xmlns:tns="urn:1" elementFormDefault="qualified"
                attributeFormDefault="unqualified">
        <xsd:include schemaLocation="B.xsd"/>
        <xsd:simpleType name="A">
            <xsd:restriction base="tns:B"/>
        </xsd:simpleType>
    </xsd:schema>
    Here is B.xsd, included from A.xsd:

    Code:
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="urn:1"
                xmlns="urn:1"
                xmlns:imported="urn:2" elementFormDefault="qualified">
        <xsd:include schemaLocation="C.xsd"/>
        <xsd:import schemaLocation="D.xsd" namespace="urn:2"/>
        <xsd:complexType name="B">
            <xsd:sequence>
                <xsd:element type="C" name="c"/>
                <xsd:element type="imported:D" name="d"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:schema>
    Here is C.xsd. Note that is has no targetNamespace, and therefore has the same target namespace as the schema it's included from (B.xsd):

    Code:
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                elementFormDefault="qualified">
        <xsd:simpleType name="C">
            <xsd:restriction base="xsd:string"/>
        </xsd:simpleType>
    </xsd:schema>
    Here is D.xsd, which is imported from B.xsd.

    Code:
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                targetNamespace="urn:2"
                xmlns="urn:2" elementFormDefault="qualified">
        <xsd:include schemaLocation="C.xsd"/>
        <xsd:simpleType name="D">
            <xsd:restriction base="C"/>
        </xsd:simpleType>
    </xsd:schema>
    Note that D.xsd also includes C.xsd, but puts it another namespace (urn:2). So C.xsd lives in two namespaces: urn:1 (included via B.xsd) and urn:2 (included via D.xsd).

    Here's a "graphical" representation of the relationships between the schemas:

    Code:
    A (urn:1)
    |
    +- B (urn:1)
       |
       +- C (urn:1)
       |
       +- D (urn:2)
          |
          +- C (urn:2)
    Given these (complex) schema's, the relevant part of the generated WSDL would be:

    Code:
    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                      xmlns:tns="http://springframework.org/spring-ws"
                      targetNamespace="http://springframework.org/spring-ws"
                      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <wsdl:types>
            <xsd:schema xmlns:urn1="urn:1"
                        xmlns:urn2="urn:2"
                        elementFormDefault="qualified"
                        targetNamespace="urn:1">
                <xsd:import namespace="urn:2"/>
                <xsd:simpleType name="A">
                    <xsd:restriction base="urn1:B"/>
                </xsd:simpleType>
                <xsd:complexType name="B">
                    <xsd:sequence>
                        <xsd:element name="c" type="urn1:C"/>
                        <xsd:element name="d" type="urn2:D"/>
                    </xsd:sequence>
                </xsd:complexType>
                <xsd:simpleType name="C">
                    <xsd:restriction base="xsd:string"/>
                </xsd:simpleType>
            </xsd:schema>
            <xsd:schema xmlns:urn2="urn:2"
                        elementFormDefault="qualified"
                        targetNamespace="urn:2">
                <xsd:simpleType name="D">
                    <xsd:restriction base="urn2:C"/>
                </xsd:simpleType>
                <xsd:simpleType name="C">
                    <xsd:restriction base="xsd:string"/>
                </xsd:simpleType>
            </xsd:schema>
        </wsdl:types>
        ...
    </wsdl:definitions>
    Note the lack of includes, and the import which has no schemaLocation. This import will be resolved to the inlined second schema, and therefore requires no schemaLocation.

    I'm interested in feedback for this. I'm currently planning to add it to 1.5 RC1, in the form of a new Wsdl11Definition class (i.e. not the XsdBasedSoap11Wsdl4jDefinitionBuilder). This class will also remove the dependency on WSDL4J, which causes headaches when running WebSphere. However, it does require a library for handling XSD schema's, because the inlining is rather complex. Currently, I'm evaluating Apache WS-Commons XML Schema, which seems to work.

    You can add feedback to this thread, or (preferably) to the related JIRA issue.
Working...
X