I am trying to parse a WSDL to get the operations, endpoint and an example payload. The WSDL in inputted by the user. I can't find a tutorial to do this.
I can only find ones that generate source code which I don't need. I've tried using XBeans but apparently I need Saxon. Is there a simple lightweight way to do this without Saxon?
E.g.
<?xml version="1.0"?>
<definitions name="StockQuote"
targetNamespace=
"http://example.com/stockquote.wsdl"
xmlns:tns="http://example.com/stockquote.wsdl"
xmlns:xsd1="http://example.com/stockquote.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema targetNamespace=
"http://example.com/stockquote.xsd"
xmlns="http://www.w3.org/2000/10/XMLSchema">
<element name="TradePriceRequest">
<complexType>
<all>
<element name="tickerSymbol"
type="string"/>
</all>
</complexType>
</element>
<element name="TradePrice">
<complexType>
<all>
<element name="price" type="float"/>
</all>
</complexType>
</element>
</schema>
</types>
<message name="GetLastTradePriceInput">
<part name="body" element=
"xsd1:TradePriceRequest"/>
</message>
<message name="GetLastTradePriceOutput">
<part name="body" element="xsd1:TradePrice"/>
</message>
<portType name="StockQuotePortType">
<operation name="GetLastTradePrice">
<input message="tns:GetLastTradePriceInput"/>
<output message="tns:GetLastTradePriceOutput"/>
</operation>
</portType>
<binding name="StockQuoteSoapBinding"
type="tns:StockQuotePortType">
<soap:binding style="document"
transport=
"http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetLastTradePrice">
<soap:operation
soapAction=
"http://example.com/GetLastTradePrice"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="StockQuoteService">
<documentation>My first service</documentation>
<port name="StockQuotePort"
binding="tns:StockQuoteBinding">
<soap:address location=
"http://example.com/stockquote"/>
</port>
</service>
</definitions>
Should get operations: GetLastTradePrice, GetLastTradePrice
Endpoint: StockQuotePort
Sample Payload:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:stoc="http://example.com/stockquote.xsd">
<soapenv:Header/>
<soapenv:Body>
<stoc:TradePriceRequest/>
</soapenv:Body>
</soapenv:Envelope>
This is like what SoapUI does. But I'm mainly concerned with being able to parse the WSDL. A bit more context is the WSDL is uploaded and then the result is displayed in a GWT application (file upload must go to the servlet). So I need to parse the file and create an object the GWT will be able to understand.
This looks nice: http://www.membrane-soa.org/soa-model-doc/1.4/java-api/parse-wsdl-java-api.htm
Didn't work on first attempt for me though, So I wrote a method that returns the suggested results for the sample wsdl - no dependencies outside of J2SE6.
public String[] listOperations(String filename) throws FileNotFoundException, SAXException, IOException, ParserConfigurationException {
Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream(filename));
NodeList elements = d.getElementsByTagName("operation");
ArrayList<String> operations = new ArrayList<String>();
for (int i = 0; i < elements.getLength(); i++) {
operations.add(elements.item(i).getAttributes().getNamedItem("name").getNodeValue());
}
return operations.toArray(new String[operations.size()]);
}
Seems like you would want to remove the duplicates, since each operation is listed twice in WSDL. That's easy using a Set. Uploaded complete eclipse project that shows both unique and non-unique results here: https://github.com/sek/wsdlparser
I use easywsdl.
A place to start
Maven:
<dependency>
<groupId>org.ow2.easywsdl</groupId>
<artifactId>easywsdl-wsdl</artifactId>
<version>2.1</version>
</dependency>
// Read a WSDL 1.1 or 2.0
WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
Description desc = reader.read(new URL("http://file/path/document.wsdl"));
// Endpoints take place in services.
// Select a service
Service service = desc.getServices().get(0);
// List endpoints
List<Endpoint> endpoints = service.getEndpoints();
// Read specific endpoint
//An endpoint has getBinding and then you getInterface from binding and so on
Endpoint specificEndpoint = service.getEndpoint("endpointName");
// Add endpoint to service
service.addEndpoint(specificEndpoint);
// Remove a specific enpoint
service.removeEndpoint("endpointName");
// Create endpoint
Endpoint createdEndpoint = service.createEndpoint();
service.addEndpoint(createdEndpoint);
My sample code:
try {
// Read a WSDL 1.1 or 2.0
WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
Description desc = reader.read(new URL("file:///C:/your/file/path/sample.wsdl"));
// Endpoints take place in services.
// Select a service
Service service = desc.getServices().get(0);
List<Endpoint> endpoints = service.getEndpoints();
//Gets address of first endpoint
System.out.println(endpoints.get(0).getAddress());
//Gets http method
System.out.println(endpoints.get(0).getBinding().getBindingOperations().get(0).getHttpMethod());
//Gets input type
System.out.println(endpoints.get(0).getBinding().getInterface().getOperations().get(0).getInput().getElement().getType().getQName().getLocalPart());
} catch (WSDLException | IOException | URISyntaxException e1) {
e1.printStackTrace();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With