I have a wsdl file without binding section:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<wsdl:definitions xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Engage" targetNamespace="http://tempuri.org/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<xs:element name="OtherData">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="id" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="OtherDataResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="OtherDataResult" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="MyData">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="id" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="MyDataResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="MyDataResult" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
<xs:element name="anyType" nillable="true" type="xs:anyType" />
<xs:element name="anyURI" nillable="true" type="xs:anyURI" />
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
<xs:element name="boolean" nillable="true" type="xs:boolean" />
<xs:element name="byte" nillable="true" type="xs:byte" />
<xs:element name="dateTime" nillable="true" type="xs:dateTime" />
<xs:element name="decimal" nillable="true" type="xs:decimal" />
<xs:element name="double" nillable="true" type="xs:double" />
<xs:element name="float" nillable="true" type="xs:float" />
<xs:element name="int" nillable="true" type="xs:int" />
<xs:element name="long" nillable="true" type="xs:long" />
<xs:element name="QName" nillable="true" type="xs:QName" />
<xs:element name="short" nillable="true" type="xs:short" />
<xs:element name="string" nillable="true" type="xs:string" />
<xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
<xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
<xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
<xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
<xs:element name="char" nillable="true" type="tns:char" />
<xs:simpleType name="char">
<xs:restriction base="xs:int" />
</xs:simpleType>
<xs:element name="duration" nillable="true" type="tns:duration" />
<xs:simpleType name="duration">
<xs:restriction base="xs:duration">
<xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
<xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
<xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
</xs:restriction>
</xs:simpleType>
<xs:element name="guid" nillable="true" type="tns:guid" />
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="FactoryType" type="xs:QName" />
<xs:attribute name="Id" type="xs:ID" />
<xs:attribute name="Ref" type="xs:IDREF" />
</xs:schema>
</wsdl:types>
<wsdl:message name="IMyService_OtherData_InputMessage">
<wsdl:part element="tns:OtherData" name="parameters" />
</wsdl:message>
<wsdl:message name="IMyService_OtherData_OutputMessage">
<wsdl:part element="tns:OtherDataResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="IMyService_MyData_InputMessage">
<wsdl:part element="tns:MyData" name="parameters" />
</wsdl:message>
<wsdl:message name="IMyService_MyData_OutputMessage">
<wsdl:part element="tns:MyDataResponse" name="parameters" />
</wsdl:message>
<wsdl:portType name="IMyService">
<wsdl:operation name="OtherData">
<wsdl:input message="tns:IMyService_OtherData_InputMessage" wsaw:Action="http://tempuri.org/IMyService/OtherData" />
<wsdl:output message="tns:IMyService_OtherData_OutputMessage" wsaw:Action="http://tempuri.org/IMyService/OtherDataResponse" />
</wsdl:operation>
<wsdl:operation name="MyData">
<wsdl:input message="tns:IMyService_MyData_InputMessage" wsaw:Action="http://tempuri.org/IMyService/MyData" />
<wsdl:output message="tns:IMyService_MyData_OutputMessage" wsaw:Action="http://tempuri.org/IMyService/MyDataResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:service name="MyService">
<wsdl:port name="xmlPort">
<http:address location="http://localhost:59109/MyService.svc/xml" />
</wsdl:port>
<wsdl:port name="jsonPort">
<http:address location="http://localhost:59109/MyService.svc/json" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Is this wsdl valid? Or in other words can we have wsdl without a binding section or it is required and this wsdl is invalid? Some tools (like SoapUI) throws exception but the other (like this https://www.wsdl-analyzer.com/) says that this is valid wsdl.
According to the W3C note about WSDL 1.1:
There may be any number of bindings for a given portType
Does it mean there can be no bindings?
Well, taking look at the XML schema for WSDL 1.1, binding element can have no occurences at all.
The practical behavior probably depends on a SOAP library. Note that the binding specifies whether we use document or RFC-style call and whether we encode the data or not.
Related
I have two environments - local and UAT which are a SOAP web service is deployed on WAS 7. The response in the local env. is proper as it sends only the fault but the uat is sending what is sent in the request + fault which is undesirable
LOCAL
request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xmlns.scania.com/logistics/schema/transport/v1">
<soapenv:Body>
<v1:TransportInformationRequest>
<!--1 or more repetitions:-->
<v1:ChassisNumber>9181398</v1:ChassisNumber>
</v1:TransportInformationRequest>
</soapenv:Body>
</soapenv:Envelope>
response
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>Faults indicating that the consumer agent is failed by a authentication or authorization mechanism.</faultstring>
<detail>
<SecurityFault>
<FaultTypeDescription>Faults indicating that the consumer agent is failed by a authentication or authorization mechanism.</FaultTypeDescription>
<CustomMessage>Security header not present in the SOAP request</CustomMessage>
</SecurityFault>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
UAT
request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xmlns.scania.com/logistics/schema/transport/v1">
<soapenv:Header/>
<soapenv:Body>
<v1:TransportInformationRequest>
<!--1 or more repetitions:-->
<v1:ChassisNumber>9181398</v1:ChassisNumber>
</v1:TransportInformationRequest>
</soapenv:Body>
</soapenv:Envelope>
response
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xmlns.scania.com/logistics/schema/transport/v1">
<soapenv:Body>
<v1:TransportInformationRequest>
<!--1 or more repetitions:-->
<v1:ChassisNumber>9181398</v1:ChassisNumber>
</v1:TransportInformationRequest>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>Faults indicating that the consumer agent is failed by a authentication or authorization mechanism.</faultstring>
<detail>
<SecurityFault>
<FaultTypeDescription>Faults indicating that the consumer agent is failed by a authentication or authorization mechanism.</FaultTypeDescription>
<CustomMessage>Security header not present in the SOAP request</CustomMessage>
</SecurityFault>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
The only difference we could spot was the local env. returns 3 namespaces xsd, xsi and soapenc in soapenvelope while UAT returns only v1 namespace.
The WSDL is :
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="TransportInformationService" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://xmlns.scania.com/logistics/schema/transport/v1"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:fault="http://xmlns.scania.com/common/schema/fault/v4"
xmlns:tns="http://xmlns.scania.com/logistics/contract/transport/v1"
xmlns:tns1="http://xmlns.scania.com/productdev/contract/part/v1"
targetNamespace="http://xmlns.scania.com/logistics/contract/transport/v1">
<types>
<xsd:schema>
<xsd:import namespace="http://xmlns.scania.com/logistics/schema/transport/v1"
schemaLocation="logistics_transport_v1.xsd" />
</xsd:schema>
</types>
<message name="GetTransportInformationRequest">
<part element="sch:TransportInformationRequest" name="parameters" />
</message>
<message name="GetTransportInformationResponse">
<part element="sch:TransportInformationResponse" name="parameters" />
</message>
<message name="EmptyChasisInformationFault">
<part element="sch:EmptyChasisFault" name="fault" />
</message>
<message name="UnknownServerFault">
<part name="UnknownServerFault" element="sch:UnknownServerFault" />
</message>
<message name="RequestMessageFormatFault">
<part name="RequestMessageFormatFault" element="sch:RequestMessageFormatFault" />
</message>
<message name="NonExistingEntityFault">
<part name="NonExistingEntityFault" element="sch:NonExistingEntityFault" />
</message>
<message name="SystemResourceUnavailableFault">
<part name="SystemResourceUnavailableFault" element="sch:SystemResourceUnavailableFault" />
</message>
<message name="SecurityFault">
<part name="SecurityFault" element="sch:SecurityFault" />
</message>
<portType name="TransportInformationDelegate">
<operation name="GetTransportInformation">
<input message="tns:GetTransportInformationRequest" />
<output message="tns:GetTransportInformationResponse" />
<fault message="tns:EmptyChasisInformationFault" name="EmptyChasisInformationFault"/>
<fault name="SystemResourceUnavailableFault" message="tns:SystemResourceUnavailableFault"/>
<fault name="NonExistingEntityFault" message="tns:NonExistingEntityFault"/>
<fault name="RequestMessageFormatFault" message="tns:RequestMessageFormatFault"/>
<fault name="UnknownServerFault" message="tns:UnknownServerFault"/>
<fault name="SecurityFault" message="tns:SecurityFault"/>
</operation>
</portType>
<binding name="TransportInformationPortBinding" type="tns:TransportInformationDelegate">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="GetTransportInformation">
<soap:operation
soapAction="http://xmlns.scania.com/logistics/contract/transport/v1/GetTransportInformation" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
<fault name="EmptyChasisInformationFault">
<soap:fault name="EmptyChasisInformationFault" use="literal" />
</fault>
<fault name="SystemResourceUnavailableFault">
<soap:fault name="SystemResourceUnavailableFault" use="literal"/>
</fault>
<fault name="NonExistingEntityFault">
<soap:fault name="NonExistingEntityFault" use="literal"/>
</fault>
<fault name="RequestMessageFormatFault">
<soap:fault name="RequestMessageFormatFault" use="literal"/>
</fault>
<fault name="UnknownServerFault">
<soap:fault name="UnknownServerFault" use="literal"/>
</fault>
<fault name="SecurityFault">
<soap:fault name="SecurityFault" use="literal"/>
</fault>
</operation>
</binding>
<service name="TransportInformationService">
<port binding="tns:TransportInformationPortBinding" name="TransportInformationPort">
<soap:address
location="http://localhost:9081/SoleilWS.WEB/TransportInformationService" />
</port>
</service>
</definitions>
The xsd :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" xmlns:types="http://ws.soleil.scania.com/"
xmlns="http://xmlns.scania.com/logistics/schema/transport/v1"
targetNamespace="http://xmlns.scania.com/logistics/schema/transport/v1">
<xs:complexType name="chassisInfo">
<xs:sequence>
<xs:element name="ChassisNumber" type="xs:int" />
<xs:element name="TransportLegs" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="From" type="xs:string" />
<xs:element name="To" type="xs:string" />
<xs:element name="OutsideEU" type="xs:boolean" />
<xs:element name="ModeOfTransport" type="xs:string" />
<xs:element name="NameOfTransport" type="xs:string"
minOccurs="0" />
<xs:element name="NationalityOfTransport" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:annotation>
<xs:documentation>Two character ISO 3166-1 code for the
nationality of the transport
</xs:documentation>
</xs:annotation>
<xs:length value="2" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Departure" type="xs:dateTime"
minOccurs="0" />
<xs:element name="EstimateTimeOfArrival" type="xs:dateTime"
minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="TransportInformationRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="ChassisNumber" type="xs:int" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="TransportInformationResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="Chassis" type="chassisInfo" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="EmptyChasisFault">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="message" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="CustomMessage">
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:simpleType name="FaultTypeDescription">
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:element name="RequestMessageFormatFault">
<xs:complexType>
<xs:sequence>
<xs:element
fixed="Request message format validation fault. Note that there may be other fault message types capturing faults for more specific request message problems."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SystemResourceUnavailableFault">
<xs:complexType>
<xs:sequence>
<xs:element
fixed="Faults which are of temporary character and not caused by incorrect request messages. This message may be used to communicate that the client can expect an invocation with the same request message to work at a later time. Example: required resource of the service realization, such as a database or another service, is temporarily inaccessible."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="UnknownServerFault">
<xs:complexType>
<xs:sequence>
<xs:element
fixed="Faults which are not classified to any other category. Note that there may be, although so should be avoided when possible, other undeclared fault message types as well."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NonExistingEntityFault">
<xs:complexType>
<xs:sequence>
<xs:element
fixed="Faults indicating that the request message is referencing an entity not existing in the service datastore."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="InvalidReferenceFault">
<xs:complexType>
<xs:annotation>
<xs:documentation>This fault may be extended using specific faults
for specific, or specific groups of, foreign keys.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element
fixed="Faults indicating that the entity contained in the request has an invalid reference to another entity."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NotSupportedForEntityStateFault">
<xs:complexType>
<xs:annotation>
<xs:documentation>This fault may be extended using specific faults
for specific, or specific groups of, state-machine rules.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element
fixed="Faults indicating that the operation issued on an entity is not permitted due to the state of the same entity."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SecurityFault">
<xs:complexType>
<xs:annotation>
<xs:documentation>This fault may be extended for specific security
faults. Remember, however, that revealing too much information on
the inner workings of a security mechanism in fault messages may
risk the security of the solution.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element
fixed="Faults indicating that the consumer agent is failed by a authentication or authorization mechanism."
name="FaultTypeDescription" type="FaultTypeDescription" />
<xs:element minOccurs="0" name="CustomMessage" type="CustomMessage" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Why the difference between the responses ?
What is the difference in the environments? Check the WAS service pack level, JVM service pack level, feature pack versions, WAS config, etc. Do both environments have the same network access?
Do your logfiles show any differences? Perhaps you can increase logging levels or turn on WAS tracing to identify the cause of the errant behaviour.
Here is the following WSDL web services xml structures:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5. -->
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://dispproj/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://dispproj/" name="DipService">
<types>
<xsd:schema>
<xsd:import namespace="http://dispproj/" schemaLocation="http://www.example.com:8888/OfficeSRV/DipPort?xsd=1" />
</xsd:schema>
</types>
<message name="getDisp">
<part name="parameters" element="tns:getDisp" />
</message>
<message name="getDispResponse">
<part name="parameters" element="tns:getDispResponse" />
</message>
<message name="getActiveoffice">
<part name="parameters" element="tns:getActiveoffice" />
</message>
<message name="getActiveofficeResponse">
<part name="parameters" element="tns:getActiveofficeResponse" />
</message>
<portType name="Dip">
<operation name="getDisp">
<input message="tns:getDisp" />
<output message="tns:getDispResponse" />
</operation>
<operation name="getActiveoffice">
<input message="tns:getActiveoffice" />
<output message="tns:getActiveofficeResponse" />
</operation>
</portType>
<binding name="DipPortBinding" type="tns:Dip">
<soap12:binding transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" style="document" />
<operation name="getDisp">
<soap12:operation soapAction="" />
<input>
<soap12:body use="literal" />
</input>
<output>
<soap12:body use="literal" />
</output>
</operation>
<operation name="getActiveoffice">
<soap12:operation soapAction="" />
<input>
<soap12:body use="literal" />
</input>
<output>
<soap12:body use="literal" />
</output>
</operation>
</binding>
<service name="DipService">
<port name="DipPort" binding="tns:DipPortBinding">
<soap12:address location="http://www.example.com:8888/OfficeSRV/DipPort" />
</port>
</service>
</definitions>
And here is the schema:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is Oracle JAX-WS 2.1.5. -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://dispproj/" version="1.0" targetNamespace="http://dispproj/">
<xs:element name="getActiveoffice" type="tns:getActiveoffice" />
<xs:element name="getActiveofficeResponse" type="tns:getActiveofficeResponse" />
<xs:element name="getDisp" type="tns:getDisp" />
<xs:element name="getDispResponse" type="tns:getDispResponse" />
<xs:complexType name="getDisp">
<xs:sequence>
<xs:element name="arg0" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="getDispResponse">
<xs:sequence>
<xs:element name="return" type="tns:disp" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="disp">
<xs:sequence>
<xs:element name="disps" type="xs:anyType" nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="getActiveoffice">
<xs:sequence />
</xs:complexType>
<xs:complexType name="getActiveofficeResponse">
<xs:sequence>
<xs:element name="return" type="tns:activeOffices" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="activeOffices">
<xs:sequence>
<xs:element name="offADDRESS" type="xs:string" minOccurs="0" />
<xs:element name="offEMAIL" type="xs:string" minOccurs="0" />
<xs:element name="offFAX" type="xs:string" minOccurs="0" />
<xs:element name="offLIECENE" type="xs:string" minOccurs="0" />
<xs:element name="offMobile" type="xs:string" minOccurs="0" />
<xs:element name="offPHONE" type="xs:string" minOccurs="0" />
<xs:element name="offid" type="xs:int" />
<xs:element name="offname" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I am using Postman (which is http request/response client) for Chrome:
Request URL: http://www.example.com:8888/OfficeSRV/DipPort
Request Body (I learned this body after testing it with: http://tomi.vanek.sk/index.php?page=wsdl-viewer):
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://dispproj/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<mns1:getActiveoffice xmlns:mns1="http://dispproj/" />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The online WSDL client successfully retrieves a result, but when I tried the url and body of the request with Postman I got the following issues:
415: Unsupported Media Type
Are there some HTTP request headers that I am missing with my requests?
After lots of tries I figured out that I have to supply the following HTTP Request Header:
Content-Type -> Content-Type: application/soap+xml;charset=UTF-8
I figured out that by using: SoapUI
We have used Web Services with Delphi in the past and those are simple with few parameters and returned a single value to the client. A new service we working should able to XML input and receive XML output.
Is there any componenet which can be used for this purpose?
When i tried using like below am getting an error "Exception in SearchAgreements input parameter XmlElement - System.NullReferenceException: Object reference not set to an instance of an object."
LDocument := NewXMLDocument;
<<framed an XML input>>
DocSearchOut := SearchArgsResponse.Create();
DoxSerchIn := SearchArgs.Create();
DoxSerchIn.SOAPTOObject(LDocument.DocumentElement,LDocument.DocumentElement,HTTPRIO1.Converter);
DoxService := GetIDoxService(True,'',HTTPRIO1);
DocSearchOut :=DoxService.SearchAgreements(DoxSerchIn)
I even tried converting SearchArgs as widestring and tried to pass as a string.This is working with minor changes on HTTPRIO execute. Final Edit
LDocument := NewXMLDocument;
<<framed an XML input>>
DocSearchOut := SearchArgsResponse.Create();
DoxSerchIn := SearchArgs.Create();
DoxSerchIn.SearchArgs := LDocument.DocumentElement.XML;
DoxService := GetIDoxService(True,'',HTTPRIO1);
DocSearchOut :=DoxService.SearchAgreements(DoxSerchIn)
its wsdl
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:i0="http://www.bank.com/dox/service/v1.0.0" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="DoxService" targetNamespace="http://tempuri.org/">
<wsdl:import namespace="http://www.bank.com/dox/service/v1.0.0" location="http://devldn.ldn.bank.com:8258/doxManual/DoxService.svc?wsdl=wsdl0"/>
<wsdl:types/>
<wsdl:binding name="BasicHttpBinding_IDoxService" type="i0:IDoxService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="SearchAgreements">
<soap:operation soapAction="http://www.bank.com/dox/service/v1.0.0/IDoxService/SearchAgreements" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DoxService">
<wsdl:port name="BasicHttpBinding_IDoxService" binding="tns:BasicHttpBinding_IDoxService">
<soap:address location="http://devldn.ldn.bank.com:8258/doxManual/DoxService.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
wsdl0
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://www.bank.com/dox/service/v1.0.0" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" targetNamespace="http://www.bank.com/dox/service/v1.0.0">
<wsdl:types>
<xsd:schema targetNamespace="http://www.bank.com/dox/service/v1.0.0/Imports">
<xsd:import schemaLocation="http://ldndev.ldn.bank.com:8258/doxManual/DoxService.svc?xsd=xsd0" namespace="http://www.bank.com/dox/service/v1.0.0"/>
<xsd:import schemaLocation="http://ldndev.ldn.bank.com:8258/doxManual/DoxService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IDoxService_SearchAgreements_InputMessage">
<wsdl:part name="parameters" element="tns:SearchAgreements"/>
</wsdl:message>
<wsdl:message name="IDoxService_SearchAgreements_OutputMessage">
<wsdl:part name="parameters" element="tns:SearchAgreementsResponse"/>
</wsdl:message>
<wsdl:portType name="IDoxService">
<wsdl:operation name="SearchAgreements">
<wsdl:input wsaw:Action="http://www.bank.com/dox/service/v1.0.0/IDoxService/SearchAgreements" message="tns:IDoxService_SearchAgreements_InputMessage"/>
<wsdl:output wsaw:Action="http://www.bank.com/dox/service/v1.0.0/IDoxService/SearchAgreementsResponse" message="tns:IDoxService_SearchAgreements_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
xsd0
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.bank.com/dox/service/v1.0.0" elementFormDefault="qualified" targetNamespace="http://www.bank.com/dox/service/v1.0.0">
<xs:element name="SearchAgreements">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="searchRequest" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" processContents="lax"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="SearchAgreementsResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="SearchAgreementsResult" nillable="true">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" processContents="lax"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
xsd1
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/">
<xs:element name="anyType" nillable="true" type="xs:anyType"/>
<xs:element name="anyURI" nillable="true" type="xs:anyURI"/>
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary"/>
<xs:element name="boolean" nillable="true" type="xs:boolean"/>
<xs:element name="byte" nillable="true" type="xs:byte"/>
<xs:element name="dateTime" nillable="true" type="xs:dateTime"/>
<xs:element name="decimal" nillable="true" type="xs:decimal"/>
<xs:element name="double" nillable="true" type="xs:double"/>
<xs:element name="float" nillable="true" type="xs:float"/>
<xs:element name="int" nillable="true" type="xs:int"/>
<xs:element name="long" nillable="true" type="xs:long"/>
<xs:element name="QName" nillable="true" type="xs:QName"/>
<xs:element name="short" nillable="true" type="xs:short"/>
<xs:element name="string" nillable="true" type="xs:string"/>
<xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte"/>
<xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt"/>
<xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong"/>
<xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort"/>
<xs:element name="char" nillable="true" type="tns:char"/>
<xs:simpleType name="char">
<xs:restriction base="xs:int"/>
</xs:simpleType>
<xs:element name="duration" nillable="true" type="tns:duration"/>
<xs:simpleType name="duration">
<xs:restriction base="xs:duration">
<xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?"/>
<xs:minInclusive value="-P10675199DT2H48M5.4775808S"/>
<xs:maxInclusive value="P10675199DT2H48M5.4775807S"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="guid" nillable="true" type="tns:guid"/>
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"/>
</xs:restriction>
</xs:simpleType>
<xs:attribute name="FactoryType" type="xs:QName"/>
<xs:attribute name="Id" type="xs:ID"/>
<xs:attribute name="Ref" type="xs:IDREF"/>
</xs:schema>
Input to Service..unfortunetely,team has added few things so unable to retrieve output on SOAP UI.
<AgreementSearchRequest xmlns="http://www.bank.com/dox/service/v1.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<PageNo>1</PageNo>
<PageSize>10</PageSize>
<Source>IBFD</Source>
</Header>
<SearchCriteria>
<AgreementId>10</AgreementId>
<AgreementStatus>Search Status</AgreementStatus>
<AgreementType>Search Type</AgreementType>
<AgreementVersion>Search Version</AgreementVersion>
<CompletedDate>2014-05-30T15:56:45.7533005+05:30</CompletedDate>
<ContractingEntity>Search GCRS Code</ContractingEntity>
<CounterpartyBranch>Search CP Branch</CounterpartyBranch>
<CounterpartyEMID>Search CP EMID</CounterpartyEMID>
<CounterpartyId>Search CP ID</CounterpartyId>
<CounterpartyName>Search CP Name</CounterpartyName>
<CounterpartyType>Search CP Type</CounterpartyType>
<CreditContact>Search Contact</CreditContact>
<IsOffshoreUser>true</IsOffshoreUser>
<Products>
<Product>
<ProductCode>Search Code</ProductCode>:=
<ProductName i:nil="true"/>
</Product>
</Products>
<RXM>Search RXM</RXM>
<RequestedDate>2014-05-30T15:56:45.758183+05:30</RequestedDate>
<bankLegalEntity>Search LEgal Entity</bankLegalEntity>
<bankLegalEntityCategory>Search Legal Entity Category</bankLegalEntityCategory>
<UmbrellaCounterpartyEMID>Search Agent EMID</UmbrellaCounterpartyEMID>
<UmbrellaCounterpartyName>Search Agent Name</UmbrellaCounterpartyName>
</SearchCriteria>
I tried importing xsd and replacing xml file HTTPRIO Before execute as mentioned here..
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.bank.com/dox/service/v1.0.0" elementFormDefault="qualified" targetNamespace="http://www.bank.com/dox/service/v1.0.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="ArrayOfProduct">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Product" nillable="true" type="tns:Product" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfProduct" nillable="true" type="tns:ArrayOfProduct" />
<xs:complexType name="Product">
<xs:sequence>
<xs:element minOccurs="0" name="ProductCode" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="ProductName" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="Product" nillable="true" type="tns:Product" />
<xs:complexType name="AgreementSearchRequest">
<xs:sequence>
<xs:element name="Header" nillable="true" type="tns:AgreementSearchRequestHeader" />
<xs:element name="SearchCriteria" nillable="true" type="tns:AgreementSearchCriteria" />
</xs:sequence>
</xs:complexType>
<xs:element name="AgreementSearchRequest" nillable="true" type="tns:AgreementSearchRequest" />
<xs:complexType name="AgreementSearchRequestHeader">
<xs:sequence>
<xs:element name="PageNo" type="xs:int" />
<xs:element name="PageSize" type="xs:int" />
<xs:element name="Source" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="AgreementSearchRequestHeader" nillable="true" type="tns:AgreementSearchRequestHeader" />
<xs:complexType name="AgreementSearchCriteria">
<xs:sequence>
<xs:element minOccurs="0" name="AgreementId" type="xs:int" />
<xs:element minOccurs="0" name="AgreementStatus" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="AgreementType" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="AgreementVersion" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CompletedDate" type="xs:dateTime" />
<xs:element minOccurs="0" name="ContractingEntity" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CounterpartyBranch" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CounterpartyEMID" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CounterpartyId" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CounterpartyName" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CounterpartyType" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="CreditContact" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="Products" nillable="true" type="tns:ArrayOfProduct" />
<xs:element minOccurs="0" name="RXM" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="RequestedDate" type="xs:dateTime" />
<xs:element minOccurs="0" name="egalEntity" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="LegalEntityCategory" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="UmbrellaCounterpartyEMID" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="UmbrellaCounterpartyName" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="AgreementSearchCriteria" nillable="true" type="tns:AgreementSearchCriteria" />
</xs:schema>
There is the Web Service Toolkit.
It has a code generator that takes a wsdl and generate Pascal classes from it that interact with the web service.
Seems to be exactly what you need, but I do not know the specifics.
Then there are also my Internet Tools for FreePascal (not Delphi).
They contain interpreter for XQuery which is a general purpose XML processing language, so you can use it with every possible XML/HTML based API with far less code than using DOM methods. But it won't help you with anything WSDL specific, you need to write the XML for every request yourself.
Based on other views on vaiours forums(inc stack overflow) we have fixed the issue by fixing in 2 places.
Changed the remotable procedure generated by Delphi.Earlier it was a class of input parameter itself so we have changed to WideString
SearchAgreements = class(TRemotable)
private
FsearchRequest: WideString ;
FsearchRequest_Specified: boolean;
procedure SetsearchRequest(Index: Integer; const AsearchRequest: WideString );
function searchRequest_Specified(Index: Integer): boolean;
public
destructor Destroy; override;
published
property searchRequest: WideString Index (IS_OPTN) read FsearchRequest write SetsearchRequest stored searchRequest_Specified;
end;
And also we have modified HTTPRIO Before execute with minor modifications and we are able to send XML sucessfully to Service.
procedure HTTPRIO1SoapBeforeExecute(const MethodName: string;
SOAPRequest: TStream);
var
StrTemp,Fheader : TStringList;
StrBeg,StrEnd,StrParam,StrParam1 : TStringList;
StreamTemp : TStream;
StrLst : TStringList;
StrLstTmp: TStringList;
begin
StrBeg:=TStringList.Create();
StrEnd:=TStringList.Create();
SOAPRequest.Position := 0;
StrTemp.LoadFromStream(SOAPRequest);
StrBeg.Text := StringReplace(StrTemp.Text,'<','<',[RfReplaceAll]);
StrEnd.Text := StringReplace(StrBeg.Text,'>','>',[RfReplaceAll]);
SOAPRequest.Position:=0;
SOAPRequest.Size := 0; //Clear the Stream
StrEnd.SaveToStream(SOAPRequest); //Reinitialise the stream with right string.
SOAPRequest.Position :=0;
end;
We have done PHd on Webservices call with,so anyone facing similar issue can contact me.Thanks:)
I have been trying to write an xslt transformation to convert 'Russian doll' style xsd into 'Venetian blind' one.
I have written something but that does not work exactly as I intended.
so I have the following xsd document:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="GX" targetNamespace="GX" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="topType">
<xs:sequence>
<xs:element name="REQUESTOR" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="RETURN_CANCELLED_CUSTOMERS" nillable="false" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="EXTERNAL_CUSTOMER_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="ON_BEHALF_OF" type="xs:string" nillable="false" minOccurs="1" maxOccurs="1"/>
<xs:element name="MSISDN_aaa" nillable="false" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="GSP_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN_bbb" nillable="false" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="SSPP_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN_ccc" nillable="false" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="SSPC_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN_ddd" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="IMSI" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
which I try to transform in to:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="GX" targetNamespace="GX" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="topType">
<xs:sequence>
<xs:element name="REQUESTOR" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="RETURN_CANCELLED_CUSTOMERS" type="tns:RETURN_CANCELLED_CUSTOMERSType" nillable="false" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RETURN_CANCELLED_CUSTOMERSType">
<xs:sequence>
<xs:element name="EXTERNAL_CUSTOMER_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="ON_BEHALF_OF" type="xs:string" nillable="false" minOccurs="1" maxOccurs="1"/>
<xs:element name="MSISDN_aaa" type="tns:MSISDN_aaaType" nillable="false" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSISDN_aaaType">
<xs:sequence>
<xs:element name="GSP_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN_bbb" type="tns:MSISDN_bbbType" nillable="false" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSISDN_bbbType">
<xs:sequence>
<xs:element name="SSPP_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN_ccc" type="tns:MSISDN_cccType" nillable="false" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSISDN_cccType">
<xs:sequence>
<xs:element name="SSPC_ID" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN_ddd" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="IMSI" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
<xs:element name="MSISDN" type="xs:string" nillable="false" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
the XSLT I am writing is very much work in progress and I am struggling ... did anyone did a similar thing and could offer a piece of advice? basically I am stuck.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes='exsl'>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="GX" targetNamespace="GX" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- processing starts here from the root element -->
<xsl:apply-templates/>
</xs:schema>
</xsl:template>
<xsl:template match="xs:complexType[not(#name)]">
<xs:complexType name="{../#name}Type">
<xs:sequence>
<xsl:apply-templates/>
<xs:element>current:<xsl:value-of select="./#name"/> parent: <xsl:value-of select="../#name"/>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element>no name = parent: <xsl:value-of select="../#name"/>
</xs:element>
</xsl:template>
<!--find the most nested complex type i.e. there are no more child complext types-->
<xsl:template match="xs:complexType[not(xs:sequence/xs:element/xs:complexType)]">
<xs:complexType name="{../#name}Type">
<xsl:copy-of select="child::node()"/>
<xs:element>current:<xsl:value-of select="./#name"/> parent: <xsl:value-of select="../#name"/>NO MORE NESTING!!!!!!!!!!!!!</xs:element>
</xs:complexType>
</xsl:template>
<xsl:template match="xs:element">
<xsl:copy>
<xsl:apply-templates select="attribute()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attribute()">
<xsl:copy/>
</xsl:template>
<xsl:template match="xs:element[xs:complexType]">
<xs:element name="{#name}" type="{#name}Type" nillable="{#nillable}" minOccurs="{#minOccurs}" maxOccurs="{#maxOccurs}"/>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
You could start off, in your root template, by simply selecting all of you complex types in the xsd
<xsl:apply-templates select="//xs:complexType" />
You would then have a template to match complex types, which don't have a name, so you can simply output them with a name based on their parent element.
<xsl:template match="xs:complexType[not(#name)]">
<xs:complexType name="{../#name}Type">
<xsl:apply-templates/>
</xs:complexType>
</xsl:template>
Finally, you would have a template to match the elements with a complex type, and add a type attribute
<xsl:template match="xs:element[xs:complexType]">
<xs:element type="{#name}Type">
<xsl:apply-templates select="#*" />
</xs:element>
</xsl:template>
Here is the full XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes='exsl'>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="GX" targetNamespace="GX" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- processing starts here from the root element -->
<xsl:apply-templates select="//xs:complexType" />
</xs:schema>
</xsl:template>
<xsl:template match="xs:complexType[not(#name)]">
<xs:complexType name="{../#name}Type">
<xsl:apply-templates/>
</xs:complexType>
</xsl:template>
<xsl:template match="xs:element[xs:complexType]">
<xs:element type="{#name}Type">
<xsl:apply-templates select="#*" />
</xs:element>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied to you XSD XML the following is output
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="GX"
targetNamespace="GX"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:complexType name="topType">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="REQUESTOR" nillable="false" type="xs:string"/>
<xs:element type="RETURN_CANCELLED_CUSTOMERSType" maxOccurs="1" minOccurs="0" name="RETURN_CANCELLED_CUSTOMERS" nillable="false"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RETURN_CANCELLED_CUSTOMERSType">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="EXTERNAL_CUSTOMER_ID" nillable="false" type="xs:string"/>
<xs:element maxOccurs="1" minOccurs="1" name="ON_BEHALF_OF" nillable="false" type="xs:string"/>
<xs:element type="MSISDN_aaaType" maxOccurs="1" minOccurs="0" name="MSISDN_aaa" nillable="false"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSISDN_aaaType">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="GSP_ID" nillable="false" type="xs:string"/>
<xs:element type="MSISDN_bbbType" maxOccurs="1" minOccurs="0" name="MSISDN_bbb" nillable="false"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSISDN_bbbType">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="SSPP_ID" nillable="false" type="xs:string"/>
<xs:element type="MSISDN_cccType" maxOccurs="1" minOccurs="0" name="MSISDN_ccc" nillable="false"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSISDN_cccType">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="0" name="SSPC_ID" nillable="false" type="xs:string"/>
<xs:element maxOccurs="1" minOccurs="0" name="MSISDN_ddd" nillable="false" type="xs:string"/>
<xs:element maxOccurs="1" minOccurs="0" name="IMSI" nillable="false" type="xs:string"/>
<xs:element maxOccurs="1" minOccurs="0" name="MSISDN" nillable="false" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
I've got the following two XSL transforms that I would like to chain together in one XSL file.
The first transform:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://schemas.xmlsoap.org/wsdl/">
<xsl:template match="/">
<xsl:copy-of select="/s0:definitions/s0:types/xs:schema"/>
</xsl:template>
</xsl:stylesheet>
And the second transform (using the output of the first as input):
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://schemas.xmlsoap.org/wsdl/">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/xs:schema/xs:element[#name='ServiceAuth']"/>
<xsl:template match="/xs:schema/xs:import[#namespace='http://www.somecompany.com/serviceAuth/ ']"/>
</xsl:stylesheet>
What I'm aiming to accomplish with this, is to copy only the xs:schema node (and all it's children) from a WSDL whilst at the same time removing two nodes from inside the xs:schema node.
How do I chain these two together in one XSL or is there an even better way to accomplish the above objective?
Below is the WSDL input file that should serve as input to the first transform:
<s0:definitions name="CBS_GetUpgradeEligibility" targetNamespace="http://www.somecompany.com/" xmlns:s0="http://schemas.xmlsoap.org/wsdl/" xmlns:s1="http://www.somecompany.com/CBS_GetUpgradeEligibility/" xmlns:s2="http://www.somecompany.com/" xmlns:s3="http://schemas.xmlsoap.org/wsdl/soap/">
<s0:types>
<xs:schema targetNamespace="http://www.somecompany.com/CBS_GetUpgradeEligibility/" xmlns:auth="http://www.somecompany.com/serviceAuth/" xmlns:cbs="http://www.somecompany.com/CBS_GetUpgradeEligibility/" xmlns:esb="http://www.somecompany.com/esbTypes/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.somecompany.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.somecompany.com/esbTypes/" schemaLocation="http://127.0.0.1:5000/CBS_GetUpgradeEligibility?SCHEMA%2FVodacom+Services%2FInfrastructure+Services%2FSchemas%2FXSD_ESBTypes"/>
<xs:import namespace="http://www.somecompany.com/serviceAuth/ " schemaLocation="http://127.0.0.1:5000/CBS_GetUpgradeEligibility?SCHEMA%2FVodacom+Services%2FInfrastructure+Services%2FSchemas%2FXSD_ServiceAuth"/>
<xs:simpleType name="DESTINATION_MSISDN">
<xs:restriction base="xs:string">
<xs:maxLength value="11"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="STRING_13">
<xs:restriction base="xs:string">
<xs:maxLength value="13"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="STRING_20">
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="UPGRADE_TYPE_DETAILS">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="isber" type="cbs:STRING_13"/>
<xs:element maxOccurs="1" minOccurs="1" name="isreward" type="cbs:STRING_13"/>
<xs:element maxOccurs="1" minOccurs="1" name="code" type="cbs:STRING_20"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="QUALIFIES_FOR_UPGRADE_DETAILS">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="isaveragespentmet" type="cbs:STRING_13"/>
<xs:element maxOccurs="1" minOccurs="1" name="is7daypremature" type="cbs:STRING_13"/>
<xs:element maxOccurs="1" minOccurs="1" name="upgradepossible" type="cbs:STRING_13"/>
<xs:element maxOccurs="1" minOccurs="1" name="upgradeduedate" type="cbs:STRING_13"/>
<xs:element maxOccurs="1" minOccurs="0" name="UpgradeType" type="cbs:UPGRADE_TYPE_DETAILS"/>
</xs:sequence>
</xs:complexType>
<xs:element name="ServiceAuth">
<xs:complexType>
<xs:sequence>
<xs:element name="Username" type="auth:Username"/>
<xs:element name="Password" type="auth:Password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetUpgradeEligibilityRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="TSORequest" type="cbs:getUpgradeEligibilityRequestElement"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="GetUpgradeEligibilityResponse">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="TSOID" type="esb:TSOID"/>
<xs:element name="TSOResponse" type="cbs:getUpgradeEligibilityResponseElement"/>
<xs:element maxOccurs="1" minOccurs="1" name="TSOResult" type="esb:TSOResult"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="getUpgradeEligibilityRequestElement">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="MSISDN" type="cbs:DESTINATION_MSISDN"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUpgradeEligibilityResponseElement">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="MSISDN" type="cbs:DESTINATION_MSISDN"/>
<xs:element maxOccurs="1" minOccurs="1" name="QualifiesForUpgrade" type="cbs:QUALIFIES_FOR_UPGRADE_DETAILS"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</s0:types>
<s0:message name="GetUpgradeEligibilityRequestMessage">
<s0:part element="s1:ServiceAuth" name="ServiceAuth"/>
<s0:part element="s1:GetUpgradeEligibilityRequest" name="GetUpgradeEligibilityRequest"/>
</s0:message>
<s0:message name="GetUpgradeEligibilityResponseMessage">
<s0:part element="s1:GetUpgradeEligibilityResponse" name="GetUpgradeEligibilityResponse"/>
</s0:message>
<s0:portType name="esbTransactionPort">
<s0:operation name="getUpgradeEligibility">
<s0:input message="s2:GetUpgradeEligibilityRequestMessage"/>
<s0:output message="s2:GetUpgradeEligibilityResponseMessage"/>
</s0:operation>
</s0:portType>
<s0:binding name="getUpgradeEligibilityEsbTransactionBinding" type="s2:esbTransactionPort">
<s3:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<s0:operation name="getUpgradeEligibility">
<s3:operation soapAction="" style="document"/>
<s0:input>
<s3:header message="s2:GetUpgradeEligibilityRequestMessage" part="ServiceAuth" use="literal"/>
<s3:body parts="GetUpgradeEligibilityRequest" use="literal"/>
</s0:input>
<s0:output>
<s3:body parts="GetUpgradeEligibilityResponse" use="literal"/>
</s0:output>
</s0:operation>
</s0:binding>
<s0:service name="getUpgradeEligibilityEsbTransactionBindingQSService">
<s0:port binding="s2:getUpgradeEligibilityEsbTransactionBinding" name="getUpgradeEligibilityEsbTransactionBindingQSPort">
<s3:address location="http://VESB14-PRD:7701/CBS_GetUpgradeEligibility"/>
</s0:port>
</s0:service>
</s0:definitions>
If you want a third stylesheet that compose those two performing the same transformation as:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://schemas.xmlsoap.org/wsdl/">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="s0:definitions/s0:types/xs:schema"/>
</xsl:template>
<xsl:template match="xs:schema/xs:element[#name='ServiceAuth']"/>
<xsl:template match="xs:schema/xs:import[#namespace='http://www.somecompany.com/serviceAuth/']"/>
</xsl:stylesheet>
Then you need:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:import href="stylesheet2.xsl"/>
<xsl:import href="stylesheet1.xsl"/>
<xsl:template match="/">
<xsl:variable name="vFirst">
<xsl:apply-imports/>
</xsl:variable>
<xsl:apply-templates select="msxsl:node-set($vFirst)/node()"/>
</xsl:template>
</xsl:stylesheet>
Output:
<xs:schema targetNamespace="http://www.somecompany.com/CBS_GetUpgradeEligibility/" xmlns:s0="http://schemas.xmlsoap.org/wsdl/" xmlns:s1="http://www.somecompany.com/CBS_GetUpgradeEligibility/" xmlns:s2="http://www.somecompany.com/" xmlns:s3="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:auth="http://www.somecompany.com/serviceAuth/" xmlns:cbs="http://www.somecompany.com/CBS_GetUpgradeEligibility/" xmlns:esb="http://www.somecompany.com/esbTypes/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.somecompany.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.somecompany.com/esbTypes/" schemaLocation="http://127.0.0.1:5000/CBS_GetUpgradeEligibility?SCHEMA%2FVodacom+Services%2FInfrastructure+Services%2FSchemas%2FXSD_ESBTypes"></xs:import>
<xs:simpleType name="DESTINATION_MSISDN">
<xs:restriction base="xs:string">
<xs:maxLength value="11"></xs:maxLength>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="STRING_13">
<xs:restriction base="xs:string">
<xs:maxLength value="13"></xs:maxLength>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="STRING_20">
<xs:restriction base="xs:string">
<xs:maxLength value="20"></xs:maxLength>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="UPGRADE_TYPE_DETAILS">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="isber" type="cbs:STRING_13"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="isreward" type="cbs:STRING_13"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="code" type="cbs:STRING_20"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="QUALIFIES_FOR_UPGRADE_DETAILS">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="isaveragespentmet" type="cbs:STRING_13"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="is7daypremature" type="cbs:STRING_13"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="upgradepossible" type="cbs:STRING_13"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="upgradeduedate" type="cbs:STRING_13"></xs:element>
<xs:element maxOccurs="1" minOccurs="0" name="UpgradeType" type="cbs:UPGRADE_TYPE_DETAILS"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="GetUpgradeEligibilityRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="TSORequest" type="cbs:getUpgradeEligibilityRequestElement"></xs:element>
</xs:sequence>
</xs:complexType></xs:element>
<xs:element name="GetUpgradeEligibilityResponse">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="TSOID" type="esb:TSOID"></xs:element>
<xs:element name="TSOResponse" type="cbs:getUpgradeEligibilityResponseElement"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="TSOResult" type="esb:TSOResult"></xs:element>
</xs:sequence>
</xs:complexType></xs:element>
<xs:complexType name="getUpgradeEligibilityRequestElement">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="MSISDN" type="cbs:DESTINATION_MSISDN"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getUpgradeEligibilityResponseElement">
<xs:sequence>
<xs:element maxOccurs="1" minOccurs="1" name="MSISDN" type="cbs:DESTINATION_MSISDN"></xs:element>
<xs:element maxOccurs="1" minOccurs="1" name="QualifiesForUpgrade" type="cbs:QUALIFIES_FOR_UPGRADE_DETAILS"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
I haven't touched XSLT for quite some time - but I think you can do it iterativly instead of by applying templates.
Start by selecting /s0:definitions/s0:types/xs:schema - then go over all of it's children (<xsl:for-each ... If i recall correctly) and for each of them test if it is the node you want to omit. if not - use copy-of, otherwise just drop it
Also, if you run the XSLT using some java code, or ANY utility you can just pass the output of the 1st XSLT as the input of the 2nd XSLT.
Hope this helps.
Since the first stylesheet is just selecting what is processed by the 2nd -- not doing any transformation itself, can't you just change copy-of to apply-templates, and import the 2nd stylesheet ? ( You don't really need to do any chaining. )
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://schemas.xmlsoap.org/wsdl/">
<xsl:import href="stylesheet-2.xsl" />
<xsl:template match="/">
<xsl:apply-templates select="/s0:definitions/s0:types/xs:schema"/>
</xsl:template>
</xsl:stylesheet>