Reading XSD from URL using Java

1.4k Views Asked by At

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();
        }
    }
2

There are 2 best solutions below

0
Shadi Al Barhouch On

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

1
jjcipher On

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.