Is there a way to use local xsd elements in WSDL - xsd

I can't seem to use local xsd element in the WSDL schema, since i can't create an external xsd (project conditions).
<types>
<xsd:schema xmlns:fs_req="urn:rg:fs_req" xmlns:sf_facto="urn:rg:sf_facto">
<xsd:import namespace="urn:rg:sf_facto" schemaLocation="ROOT_sf_facto_SF_facto_V00_05.xsd" />
<xsd:import namespace="urn:rg:fs_req" schemaLocation="ROOT_fs_req_fs_req_V00_04.xsd" />
<xsd:element name="getDetailsAction1" type="fs_req:fs_req_fs_req" /
<xsd:element name="getDetailsAction1Response" type="sf_facto:SF_facto_SF_facto"/>
</xsd:schema>
</types>
Below the call of the xsd element (Not valide part!)
<message name="detailMpaResponse">
<part name="getDetail" element="tns:getDetailsAction1Response" />
</message>
<message name="detailMpaRequest">
<part name="getDetailResponse" element="tns:getDetailsAction1" />
</message>
How can i have a valide wsdl with the local xsd element?

The problem looks to be with your namespace qualifier in the <part> nodes.
EDIT:
In looking closer at your original post I think the schema element might hold the values we need. Give this code a shot:
<message name="detailMpaResponse">
<part name="getDetail" element="fs_req:getDetailsAction1Response" />
</message>
<message name="detailMpaRequest">
<part name="getDetailResponse" element="sf_facto:getDetailsAction1" />
</message>

You need to declare a new targetNamespace for the xs:schema in your wsdl:types and add it to wsdl:definitions, something like this:
<types>
<xsd:schema xmlns:types="urn:rg:types" targetNameSpace="urn:rg:types" xmlns:fs_req="urn:rg:fs_req" xmlns:sf_facto="urn:rg:sf_facto">
<xsd:import namespace="urn:rg:sf_facto" schemaLocation="ROOT_sf_facto_SF_facto_V00_05.xsd" />
<xsd:import namespace="urn:rg:fs_req" schemaLocation="ROOT_fs_req_fs_req_V00_04.xsd" />
<xsd:element name="getDetailsAction1" type="fs_req:fs_req_fs_req" />
<xsd:element name="getDetailsAction1Response" type="sf_facto:SF_facto_SF_facto"/>
</xsd:schema>
</types>
then add the new namespace to wsdl:definitions:
xmlns:types="urn:rg:types"
and then refer to it in the message parts:
<message name="detailMpaResponse">
<part name="getDetail" element="types:getDetailsAction1Response" />
</message>
<message name="detailMpaRequest">
<part name="getDetailResponse" element="types:getDetailsAction1" />
</message>
The new namespace can't match the ones you import.

Just did a quick experiment (using Eclipse WSDL editor), and the following code was generated when I selected "using a type" from an external XSD (in the same directory as the WSDL file):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.org/NewWSDLFile/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NewWSDLFile"
targetNamespace="http://www.example.org/NewWSDLFile/" xmlns:xsd1="http://www.example.org/NewXMLSchema">
<wsdl:types>
(...)
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.example.org/NewXMLSchema"
schemaLocation="NewXMLSchema.xsd">
</xsd:import>
</xsd:schema>
</wsdl:types>
<wsdl:message name="NewOperationRequest">
<wsdl:part name="parameters" type="xsd1:externalSchemaParamType" />
</wsdl:message>
(...)
In your case: is "tns" the name space of the externa XSD?

Related

Apache CXF Generated JAXB class has #XMLElement with Blank/Empty "" Namespace for External Schema/XSD

I am using Apache CXF maven cxf-codegen-plugin (wsdl2java) to generate JAXB classes from wsdl which includes external XSD and uses the complex type in XSD to define element.
pom.xml Snippet -
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOption>
<wsdl>${base.wsdl.path}/myWSDL.wsdl</wsdl>
<extraargs>
<extraarg>-p</extraarg>
<extraarg>${base.package.name}.mywsdl</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
myWSDL.wsdl Snippet-
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="myService"
targetNamespace="http://com.company/myservice/schemas">
<wsdl:types>
<xs:schema xmlns="http://com.company/myservice/schemas"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://com.company/myservice/schemas">
<xsd:include schemaLocation="myXSD.xsd"/>
<xsd:complexType name="myElementType">
<xsd:sequence>
<xsd:element name="MyElementXSD" type="MyElementComplexTypeFromXSD" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xs:element name="MyElement" type="myElementType"/>
...
...
</xs:schema>
</wsdl:types>
myXSD.xsd -
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com.company/myservice/schemas" targetNamespace="http://com.company/myservice/schemas">
<complexType name="MyElementComplexTypeFromXSD">
<attribute name="MyAttribute" type="string"/>
</complexType>
</schema>
Generated MyElement.java -
public class MyElement {
#XmlElement(name = "MyElementXSD", namespace="", required = true)
protected MyElementXSD myElementXSD;
}
With these WSDL and XSD, generated JAXB class has explicitly empty namespace which is causing issue during unmarshalling.
If I modify WSDL and XSD as below, generated JAXB class is proper and unmarshalling works just fine.
Create element of complex type directly in XSD -
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com.company/myservice/schemas" targetNamespace="http://com.company/myservice/schemas">
<element name="MyElementXSD">
<complexType >
<attribute name="MyAttribute" type="string"/>
</complexType>
</element>
</schema>
Refer to it directly using 'ref' instead of 'type' in WSDL -
<xsd:complexType name="myElementType">
<xsd:sequence>
<xsd:element ref="MyElementXSD" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
Then generated class #XmlElement changes to -
public class MyElement {
#XmlElement(name = "MyElementXSD", required = true)
protected MyElementXSD myElementXSD;
}
But I am not at liberty to touch provided WSDLs and XSDs, hence looking for solutions/suggestions such as passing some argument to CXF maven plugin/using a binding file etc.

How does xsd:any ##other behave when part of an extension

When extending the Oasis BaseFaultType from another xsd of a different namespace would the xsd:any ##other by default put all of the extended class members within it?
This is the relevant part of Oasis BaseFaultType
<xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType" />
<xsd:complexType name="BaseFaultType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="lax" />
<xsd:element name="Timestamp" type="xsd:dateTime" />
<xsd:element minOccurs="0" name="Originator" type="wsa:EndpointReferenceType" />
<xsd:element minOccurs="0" name="ErrorCode">
And here is the example of the extension
<xsd:schema xmlns:ws-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:cmn="http://customer.com/schema/common/v1" xmlns:tns="http://customer.com/contract/vfo/fault/v1" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://customer.com/contract/vfo/fault/v1" version="1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import schemaLocation="./bf-2.xsd" namespace="http://docs.oasis-open.org/wsrf/bf-2" />
<xsd:import schemaLocation="./Meta.xsd" namespace="http://customer.com/schema/common/v1" />
<xsd:import schemaLocation="./CodeLists.xsd" namespace="http://customer.com/schema/common/v1" />
<xsd:element name="Fault" type="tns:FaultType">
</xsd:element>
<xsd:complexType name="FaultType">
<xsd:complexContent mixed="false">
<xsd:extension base="ws-bf:BaseFaultType">
<xsd:sequence>
<xsd:element minOccurs="0" name="Name" type="xsd:normalizedString">
</xsd:element>
Which is part of a parent XSD
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:cmn="http://customer.com/schema/common/v1" xmlns:tns="http://customer.com/contract/vho/header/v1" xmlns:vfo="http://customer.com/contract/vfo/fault/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://customer.com/contract/vho/header/v1" version="1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import schemaLocation="./Fault.xsd" namespace="http://customer.com/contract/vfo/fault/v1" />
<xsd:element name="Source" type="tns:SourceType" />
<xsd:element name="Destination" type="tns:DestinationType" />
<xsd:element name="Correlation" type="tns:CorrelationType" />
<xsd:element name="Cache" type="tns:CacheType" />
<xsd:element name="ServiceDocumentation" type="tns:ServiceDocumentationType" />
<xsd:element name="ResultStatus" type="vfo:FaultType" />
What I need is an XSD expert to tell me if this complies to W3C standard when the xml response expected is as follows :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<tns:ResultStatus xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:vfo="http://customer.com/contract/vfo/fault/v1" xmlns:cmn="http://customer.com/schema/common/v1" xmlns:ns3="http://www.w3.org/2005/08/addressing" xmlns:ns2="http://docs.oasis-open.org/wsrf/bf-2" xmlns:ns1="urn:un:unece:uncefact:documentation:standard:CoreComponentType:2" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://customer.com/contract/vho/header/v1">
<vfo:Name>1006</vfo:Name>
<vfo:Message>Invalid ChargeAccountNumber (not found).</vfo:Message>
<ns2:Timestamp>2017-06-19T10:18:48.467+01:00</ns2:Timestamp>
</tns:ResultStatus>
</soapenv:Header>
<soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
</soapenv:Envelope>
In this cut for brevity example, would the Name value belong to the Any structure of BaseFaultType or the parent extension FaultType? And if not, why not?
Are there any tools that would allow me to report on the validity of the response against the schema?
BaseFault cannot be extended outside of its own namespace. The flaw was never corrected during early design :
https://lists.oasis-open.org/archives/wsrf/200506/msg00060.html

JAXB Unmarshal - Elements missing and elements in not in order

I am trying to unmarshal an XML that I marshalled before.
In the unmarshalled result, I am missing elements and the elements I get are not in the same order as the input XML. I've created a afterUnmarshal() listener and I see the elements there, but not in the resulting Java Object.
The XSD is structured like this (a 'fanout'-node, for example, can contain another set of processSteps, so it can be deeply nested (tree)):
<xsd:element name="process">
<xsd:annotation>
<xsd:documentation>Integration Process</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<!-- more -->
<xsd:element name="itinerary" type="lwis:itineraryType"/>
<!-- more -->
</xsd:complexType>
</xsd:element>
<xsd:complexType name="itineraryType">
<xsd:sequence>
<xsd:element name="step" type="lwis:stepType"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="step" type="lwis:stepType"/>
<xsd:element name="fanout" type="lwis:fanoutType"/>
<xsd:element name="decision">
<xsd:complexType>
<!-- snip.. -->
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
I suppose the order is given by the SAX parser, but I can't imagine a SAX parser would change the order for no reason? At the moment, the first element in the list is the last one in the XML. The second element in the list is the third in the XML - it seems random..
Thanks for any help!
Sample Input:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<process name="My.Process" description="My Process description" qualityOfService="AT_LEAST_ONCE" entryEndpoint="ENTRY.EP" xmlns="http://www.xxxxx.com/ns/yyyy">
<faultEndpoint endpoint_ref="EXIT.EP"/>
<rejectEndpoint endpoint_ref="EXIT.EP"/>
<itinerary>
<step name="Step 1" endpoint_ref="Step1.EP" type="SERVICE"/>
<step name="Step2-CBRStep" endpoint_ref="Step2.EP" type="SERVICE"/>
<decision name="Decision-nonameneeded">
<option name="op1">
<step name="Step 2A" endpoint_ref="Step2a.EP" type="SERVICE"/>
</option>
<option name="op2">
<step name="Step 2B" endpoint_ref="Step2a.EP" type="SERVICE"/>
</option>
</decision>
<step name="Step 3" endpoint_ref="Step3.EP" type="SERVICE"/>
<fanout name="Fan1">
<path>
<step name="Step4A" endpoint_ref="Step4A.EP" type="SERVICE"/>
</path>
<path>
<step name="Step4B" endpoint_ref="Step4B.EP" type="SERVICE"/>
<step name="Step5" endpoint_ref="Step5.EP" type="SERVICE"/>
</path>
</fanout>
<step name="Step6" endpoint_ref="Step6.EP" type="SERVICE"/>
</itinerary>
</process>
Object:
Process Object has a field with itinerary of Type ItineraryType which:
step = StepType ("Step6" from XML)
stepOrFanoutOrDecision = ArrayList:
item 0: ItineraryType$Decision ("Decision-nonameneeded" from XML)
option 0: "op1" from XML
step: "Step 2A" from XML
option 1: "op2" from XML
step: "Step 2B" from XML
item 1: FanoutType ("Fan1" from XML)
path 0:
step: Step4A
path 1:
step: Step5
Step 1, Step2-CBRStep and Step 4B is missing?
I have the toString() output of the itinerary here:
com.x.ItineraryType#fe39ebf[step=com.x.StepType#28cb15bf[endpointRef=Step6.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step6, description=<null>], stepOrFanoutOrDecision={com.x.ItineraryType$Decision#2d00c385[option={com.x.ItineraryType$Decision$Option#d2467d8[step=com.x.StepType#511d9ca5[endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2A, description=<null>], stepOrFanoutOrDecision=<null>, name=op1],com.x.ItineraryType$Decision$Option#6f173e3d[step=com.x.StepType#5ef74fc5[endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2B, description=<null>], stepOrFanoutOrDecision=<null>, name=op2]}, name=Decision-nonameneeded, description=<null>],com.x.FanoutType#3e963f38[path={com.x.FanoutType$Path#7a1095a1[step=com.x.StepType#56cfbba2[endpointRef=Step4A.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step4A, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>],com.x.FanoutType$Path#6027b534[step=com.x.StepType#4ee99a3d[endpointRef=Step5.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step5, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>]}, name=Fan1, description=<null>]}]
Ant Script I'm using: with extensions hashCode, toString and equals:
<?xml version="1.0" encoding="UTF-8"?>
<project name="RunningXjc" default="generate-sources" basedir=".">
<description>Runs Xjc Binding Compiler</description>
<target name="generate-sources">
<taskdef name="xjc" classname="org.jvnet.jaxb2_commons.xjc.XJC2Task">
<classpath>
<fileset dir="buildLib/jaxb-ri-2.2.6/lib">
<include name="*" />
</fileset>
<fileset dir="buildLib/jaxb2-basics-dist-0.6.4/dist">
<include name="jaxb2-basics-ant-*.jar" />
</fileset>
</classpath>
</taskdef>
<!-- Generate the Java code for XSD -->
<xjc destdir="${basedir}/target/generated-sources/xjc" extension="true">
<arg
line="
-Xequals
-XhashCode
-XtoString
-Xcopyable
-Xmergeable" />
<binding dir="${basedir}/src">
<include name="**/*.xjb" />
</binding>
<schema dir="${basedir}/schema">
<include name="processSlim.xsd" />
</schema>
<!-- Plugins -->
<classpath>
<fileset dir="${basedir}/buildLib/jaxb2-basics-dist-0.6.4">
<!-- JAXB2 Basics library -->
<include name="dist/jaxb2-basics-*.jar" />
<!-- JAXB2 Basics library dependencies -->
<include name="dist/jaxb2-basics-runtime-*.jar" />
<include name="dist/jaxb2-basics-tools-*.jar" />
<include name="lib/commons-beanutils-*.jar" />
<include name="lib/commons-lang-*.jar" />
<include name="lib/commons-logging-*.jar" />
<include name="lib/javaparser-*.jar" />
<include name="lib/annox-*.jar" />
</fileset>
</classpath>
</xjc>
</target>
</project>
PROBLEM
From Your XML Schema
Below is a fragment from your XML schema. The itineraryType contains a sequence where a step element can occur both inside and outside of the choice structure.
<xsd:complexType name="itineraryType">
<xsd:sequence>
<xsd:element name="step" type="lwis:stepType" />
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="step" type="lwis:stepType" />
<xsd:element name="fanout" type="lwis:fanoutType" />
<xsd:element name="decision">
<xsd:complexType>
<!-- snip.. -->
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
ItineraryType
This is causing the step element to be mapped to two different properties which is causing your problem.
public class ItineraryType {
#XmlElement(required = true)
protected StepType step;
#XmlElements({
#XmlElement(name = "step", type = StepType.class),
#XmlElement(name = "fanout", type = FanoutType.class),
#XmlElement(name = "decision", type = ItineraryType.Decision.class)
})
protected List<Object> stepOrFanoutOrDecision;
...
}
SOLUTION
You can use the simple binding mode extension in the JAXB XJC tool to support this use case. It will automatically prevent the step property from being created. You can specify this via an external binding document like the following:
bindings.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
version="2.1">
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
</jxb:bindings>
XJC Call
Below is how the external bindings file is referenced in an XJC call. You will need to also use the -extension flag to enable the XJC extension to be used.
xjc -extension -b bindings.xml schema.xsd

Custom XSD for xhtml

i trying the following but getting an error
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsd:import namespace="http://www.w3.org/1999/xhtml" schemaLocation="xhtml.xsd" />
<xsd:element name="book" type="bookType"/>
<xsd:complexType name="bookType">
<xsd:all>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element ref="xhtml:pre"/>
<xsd:element ref="xhtml:ul"/>
</xsd:all>
</xsd:complexType>
</xsd:schema>
its returning an error on <xsd:element ref="xhtml:pre"/>
Try this:
<xsd:import namespace="http://www.w3.org/1999/xhtml" schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd" />
Instead of your import. It will validate in XML Spy.

Nillable SOAP headers

I would like to allow some of my SOAP header elements to be nillable. This is possible for body elements, but I am not sure if it is allowed from header elements.
In the sample message below, I would like to allow the MessageDateTime to be null.
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://mycompany.com/repositoryservice">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://mycompany.com/repositoryservice">
<element name="MessageDateTime" type="dateTime" />
<element name="SaveRequest">
<!-- complexType -->
</element>
</schema>
</types>
<message name="SaveRequest_Headers">
<part name="MessageDateTime" element="tns:MessageDateTime" />
</message>
<message name="SaveRequest">
<part name="parameters" element="tns:SaveRequest" />
</message>
<binding name="RepositoryServiceBinding" type="tns:IRepositoryService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="Save">
<soap:operation soapAction="http://mycompany.com/repositoryservice/Save" style="document" />
<input name="SaveRequest">
<soap:header message="tns:SaveRequest_Headers" part="MessageDateTime" use="literal" />
<soap:body use="literal" />
</input>
</operation>
</binding>
<!-- service, portType -->
</definitions>
It is allowed as long as the definition allows for it. In your case, all you have to do is add the nillable="true" to the element's definition. The result on .NET w/ WCF would look something like this:
[System.ServiceModel.MessageHeaderAttribute(Namespace="...")]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public System.Nullable<System.DateTime> MessageDateTime;

Resources