6

Objective : I want to read a WSDL and print the services in the WSDL, complex types and Complex type definitions.

Worked : I've used WSDL4J for reading WSDL and successfully able to print the services and their parameters (complex types). Now I want to read the complex type definitions which is available in XSD. I'm unable to read XSD .Is ther any way to do it ?

I'm getting XSModel as null

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.wsdl.xml.WSDLReader;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;

import com.ibm.wsdl.BindingImpl;
import com.ibm.wsdl.xml.WSDLReaderImpl;
import com.sun.org.apache.xerces.internal.impl.xs.XSImplementationImpl;
import com.sun.org.apache.xerces.internal.xs.XSLoader;
import com.sun.org.apache.xerces.internal.xs.XSModel;

public class WSDLDetails {

    public static void main(String[] args) {
        try {
            String wsdlURL = "https://abc.xyz.com/webservice/MessagingSevice?WSDL";
            String xsdURL = "https://abc.xyz.com/webservice/MessagingSevice?xsd=1";
            java.lang.System.setProperty("https.protocols", "TLSv1.2");
            getAllBindingOperation(wsdlURL);
            readXSD(xsdURL);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<String> getAllBindingOperation(String wsdlUrl) {
        List<BindingOperation> operationList = new ArrayList();
        List<String> nameList = new ArrayList();
        try {
            WSDLReader reader = new WSDLReaderImpl();
            reader.setFeature("javax.wsdl.verbose", false);
            Definition definition = reader.readWSDL(wsdlUrl.toString());
            Map<String, BindingImpl> defMap = definition.getAllBindings();
            Collection<BindingImpl> collection = defMap.values();
            for (BindingImpl binding : collection) {
                operationList.addAll(binding.getBindingOperations());
            }
            for (BindingOperation operation:operationList) {
                nameList.add(operation.getName());
                System.out.println("Name     :: " + operation.getName());
                System.out.println("Request  :: " + operation.getBindingInput());
                System.out.println("Response :: " + operation.getBindingOutput());
            }
        } catch (WSDLException e) {
            System.out.println("get wsdl operation fail.");
            e.printStackTrace();
        }
        return nameList;
    }

    public static void readXSD(String xsdURL) {
        try {
            System.setProperty(DOMImplementationRegistry.PROPERTY, "com.sun.org.apache.xerces.internal.dom.DOMXSImplementationSourceImpl");
            DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); 
            com.sun.org.apache.xerces.internal.impl.xs.XSImplementationImpl impl = (XSImplementationImpl) registry.getDOMImplementation("XS-Loader");
            XSLoader schemaLoader = impl.createXSLoader(null);
            XSModel model = schemaLoader.loadURI(xsdURL);
            System.out.println(model);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
Anandhakrishnan
  • 548
  • 2
  • 7
  • 21
  • The XSD referenced by your WSDL should be a standard XSD, you can read it as XML, search for nodes using the xpath //complexType/@name and voila, you should have the ComplexType names. – m4gic Feb 18 '19 at 14:35

2 Answers2

0

You can use xsd2java plugin with maven https://github.com/qaware/xsd2java-gradle-plugin

0

Here is an example showing how to retrieve the XSModel from an XSD URL, and print the complex types declared therein.

import org.apache.xerces.impl.xs.XMLSchemaLoader;
import org.apache.xerces.impl.xs.XSComplexTypeDecl;
import org.apache.xerces.impl.xs.XSElementDecl;
import org.apache.xerces.xs.XSConstants;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSNamedMap;
import org.apache.xerces.xs.XSTypeDefinition;

public class Test {

  public static void main(String[] args) {
      try {
          String xsdURL = "http://fsharp.github.io/FSharp.Data/data/po.xsd";
          XMLSchemaLoader xsLoader = new XMLSchemaLoader();
          XSModel xsModel = xsLoader.loadURI(xsdURL);

          // print global element declarations
          System.out.println("\nGlobal Element Declarations:");
          XSNamedMap globalElemDecls = xsModel.getComponents(XSConstants.ELEMENT_DECLARATION);
          globalElemDecls.forEach((k,v) -> System.out.println((XSElementDecl) v));

          // print global complex type declarations
          System.out.println("\nGlobal Complex Type Declarations:");
          XSNamedMap globalComplexTypeDecls = xsModel.getComponents(XSTypeDefinition.COMPLEX_TYPE);
          globalComplexTypeDecls.forEach((k,v) -> System.out.println((XSComplexTypeDecl) v));

      } catch (Exception e) {
          e.printStackTrace();
      }
    }
}

If you got null at xsLoader.loadURI(xsdURL), it is likely there are some flaws in the given XSD file. For example, "White spaces are required between publicId and systemId". You might need to fix these flaws first.

jjcipher
  • 147
  • 1
  • 2
  • 7
  • @jj Hello, I using the `xerces 2` to parse my XML but I am unable to get the elements present with in complex type and their data type. I am unable to find any examples in which they are doing this, can you please check and respond to this thread if possible: https://stackoverflow.com/questions/66856898/how-access-any-element-from-xsd-and-get-its-datatype-and-other-related-informati Thanks in advance – BATMAN_2008 Mar 29 '21 at 20:00