Currently working on a project in which the xsd's have been provided for data exchange. The xsd's are available isotc211. As can be seen there are a couple of them and i am interested in generation of classes for /gmd/metadataEntity.xsd which in turn has dependencies on other xsds and so on.
The problem is that there is a lot of repetition of names for elements and attributes and it would be a really long job to get rid of them and at the end i am not even sure if it will work. i have this till now ..
<jxb:bindings version="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" >
<jxb:bindings schemaLocation="geometryPrimitives.xsd" node="/xsd:schema">
<jxb:schemaBindings>
<jxb:package name="net.opengis.gml"/>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
<jxb:bindings
node="//xsd:group[#name='PointGrid']/xsd:sequence/xsd:element[#name='rows']">
<jxb:property name="rowsElement"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>`
the namexml transform was supposed to help to take care of the element and attributes naming but i still have a lot of similary naming across the xsd's. is there a way of getting around this ?
For instance elements are now generated using the suffix. so i get net.open.gml.SecondDefiningParameterElement is already in use.
when something like this exists in one of the xsd's
<element name="secondDefiningParameter"><complexType>
<sequence>
<element ref="gml:SecondDefiningParameter"/>
</sequence>
</complexType>
</element>
and in the same xsd
<element name="SecondDefiningParameter">
<complexType>
<choice>
<element name="inverseFlattening" type="gml:MeasureType"/>
<element name="semiMinorAxis" type="gml:LengthType"/>
<element name="isSphere">
<simpleType>
<restriction base="string">
<enumeration value="sphere"/>
</restriction>
</simpleType>
</element>
</choice>
</complexType>
</element>
Related
The application uses spring ws to build a SOAP webservice. The XSD of the payload includes another XSD schema file that includes a reusable component (header, etc...) across multiple schema files.
I am able to successfully generate the corresponding Java objects using JAXB.
The dispatcher servlet is below:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd">
<import resource="service-context.xml" />
<sws:annotation-driven />
<context:component-scan
base-package="com.test.service" />
<!-- SOAP Fault Annotation Exception Resolver -->
<bean
class="org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver" />
<!-- ############## WSDL Definitions ################## -->
<sws:dynamic-wsdl id="sampleEndpoint"
portTypeName="sampleEndpoint" locationUri="/sampleEndpoint/">
<sws:xsd location="/WEB-INF/xsd/samplePayload.xsd" />
</sws:dynamic-wsdl>
</beans>
A snippet of the main *.xsd file that includes a second schema:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:abc="www.example.com">
<xsd:include schemaLocation="common.xsd"></xsd:include>
<element name="SampleRequest">
<complexType>
<sequence>
<element name="MsgRqHdr">
<complexType>
<sequence>
<element name="UID" type="string" minOccurs="1"
maxOccurs="1" />
</sequence>
</complexType>
</element>
.........
The application is deployed to an Apache Tomcat v9 server. The wsdl is tested on a browser to be successful; I can spot all the operations provided in this wsdl, and the included *.xsd schema file is visible as well:
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="www.example.com" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="www.example.com" targetNamespace="www.example.com">
<wsdl:types>
<xsd:schema xmlns="www.example.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="www.example.com">
**<xsd:include schemaLocation="common.xsd"/>**
<xsd:element name="SampleRq" type="SampleRq_Type"/>
<xsd:element name="SampleRs" type="SampleRs_Type"/>
<xsd:annotation>
<xsd:documentation source="DES">
..........
Now to test with SoapUI. The project creation fails with the comment:
Error loading [http://localhost:8080/sample/common.xsd]: org.apache.xmlbeans.XmlException: org.apache.xmlbeans.XmlException: error: Unexpected end of file after nul
I refer to the following issues raised previously:
1- xsd:include exception in soapUI:org.apache.xmlbeans.XmlException: org.apache.xmlbeans.XmlException: error: Unexpected end of file after null
2- soapUI - issue with wsdl that includes xsd
Which indicates that the WSDL fails to find this schema file for some reason. I have searched StackOverflow for similar issues which almost exactly describes my case but there is no definitive answer. At most, the issue has been diagnosed with no additional information on how to properly fix it.
If I try to open the *.xsd file in another browser tab I fail to open it, it cannot be found. So the issue is in defining a correct path to the document which I have no idea how to do it.
Question is, How to properly define and/or include *.xsd schema files inside on another so that it can be identified correctly?
Thank you in advance,
I'm also using an included . xsd from another, but i'm using the import tag instead. My main .xsd looks like this
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://My_WS_01_00_00.Local"
xmlns:tns="http://My_WS_01_00_00.Local"
xmlns:ts="http://jaxb2-commons.dev.java.net/basic/toString"
elementFormDefault="qualified" xmlns:pref="http://Types_WS_01_00_00">
<import schemaLocation="../../1.0.0/My_WS_Types.xsd" namespace="http://Types_WS_01_00_00"></import>
<element name="LoginRequest">
<complexType>
<sequence>
<element name="username" type="string" />
<element name="password" type="string" />
</sequence>
</complexType>
</element>
<element name="LoginResponse">
<complexType>
<sequence>
<element name="answer" type="int" />
<element name="operator" type="pref:WS_Operator" />
</sequence>
</complexType>
</element>
And my included .xsd is like this:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://Types_WS_01_00_00"
xmlns:tns="http://Types_WS_01_00_00"
elementFormDefault="qualified">
<complexType name="WS_Operator">
<sequence>
<element name="id" type="long" />
<element name="username" type="string" />
<element name="name" type="string" />
<element name="surname" type="string" />
<element name="language" type="long" />
</sequence>
</complexType>
Hope it helps you,
I'm stuck on a problem with JAXB / Spring Web Services. Below is the detailed description. I appreciate any suggestion that could help me to solve it. I can provide more if details if needed.
I am writing a web service that returns list of some entities. Spring WS is contract-first framework, so I started with the XSD similar to:
<element name="GetEntitiesRequest" type="Something"/>
<element name="GetEntitiesResponse" type="Entities"/>
<complexType name="Entities">
<sequence>
<element name="Entity" type="Entity" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="Entity">
<sequence>
(...)
</sequence>
</complexType>
It was working well. However, the "Entity" type begin to grow (there a lot of elements) which caused performance issues (there are many Entities in the response). So I decided to split "Entity" into two parts
Some general information that will be returned within the group response - Entity
More detailed information that will be returned in an another web service operation, specific for the entity - EntityDetails
So after the change the schema is as follows (EntityDetails inherits from Entity):
<element name="GetEntitiesRequest" type="Something"/>
<element name="GetEntitiesResponse" type="Entities"/>
<complexType name="Entities">
<sequence>
<element name="Entity" type="Entity" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="Entity">
<sequence>
(...)
</sequence>
</complexType>
<element name="GetEntityDetailsRequest" type="SomethingMore"/>
<element name="GetEntityDetailsResponse" type="EntityDetails"/>
<complexType name="EntityDetails">
<complexContent>
<extension base="Entity">
<sequence>
(...)
</sequence>
</extension>
</complexContent>
</complexType>
JAXB (precisely: hyperjaxb3) generates classes for Entity (inheritance strategy = JOINED), EntityDetails, and Entities. Also, it creates the ObjectFactory with "createGetEntitiesResponse" method. I am using this method to marshall List retrieved through Hibernate from the Entity table.
Theoretically, I should get list of "Entity" when sending "GetEntitiesRequest". However, I get list of "EntityDetails" instead.
If you read this form the beginning, you can imagine, that this what I wanted to avoid.
If you need more details, persistence.xml is as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence (...)>
<persistence-unit name="org.package">
<class>org.package.Entity</class>
<class>org.package.EntityDetails</class>
<class>org.package.Entities</class>
</persistence-unit>
</persistence>
I use Gradle for the build automation, and its jaxb plugin for the class generation:
jaxb
{
xsdDir = "src/main/webapp/schemas/messages"
bindingsDir = "src/main/webapp/schemas/bindings"
bindings = ["bindings.xjb"]
xjc
{
extension = true
taskClassname = "com.sun.tools.xjc.XJC2Task"
generatePackage = "org.package"
args = ["-Xannotate", "-Xhyperjaxb3-jpa2", "-Xequals", "-XhashCode", "-XtoString"]
}
}
currently, the bindings.xjb, beyond header, contains only:
<jaxb:globalBindings localScoping="toplevel">
<xjc:serializable/>
</jaxb:globalBindings>
First of all, make sure that you get instances Entity from the database, NOT EntityDetails.
Try to create an isolated scenario, without the database. Just instantiate your Entity, fill it with something create the response and marshal it. See what happens.
You'll isolate the problem - either you're getting wrong instances from the database or the marshalling does not work as expected. Both is a bit hard to diagnose without seeing your code. Try to reduce your problem to one of the two I mentioned above.
Diclaimer: I'm the author of Hyperjaxb3.
Consider this piece of XML
<Parent id="MyParent1">
<Child id="MyParent1.MyChild1"/>
</Parent>
<Parent id="MyParent2">
<Child id="MyParent2.MyChild1"/>
<Child id="MySillyIncorrectPrefix.MyChild2"/>
</Parent>
How can I validate (possibly with XSD) Child elements whose id contains the Parent element id as a prefix, so that:
<Child id="MyParent2.MyChild1"/> <!-- is valid -->
<Child id="MySillyIncorrectPrefix.MyChild2"/> <!-- is not valid -->
I'm not bound to XSD version 1.0, so I could try with XSD 1.1 (and features like assertions), but I would like to know:
how to express the above constraint with an xs:assertion or more suitable XSD 1.1
feature.
if it's possible to build a validator in Java leveraging on
that xsd? "Xerces-J" is a feasible solution ?
In my limited knowledge of XSD 1.1 I came up with this attempt:
<xs:element name="Child">
<xs:complexType>
<xs:attribute name="type" type="xs:String" />
<xs:assert test="starts-with(#type,../#type)"/>
</xs:complexType>
</xs:element>
Is this correct? Is there a tool where I could test it?
Being more general: is there a tool to assist the build&test of such XSD 1.1 featured schemas? (afaik Eclipse supports only XSD 1.0)
What you describe is not feasible in XSD 1.0.
In XSD 1.1 you can use assertions on the type of the parent to require each child's id attribute to begin with the value of the parent's id attribute.
This schema should validate the example (use an xsd 1.1 assertion)
<?xml version="1.1" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/stackoverflow" xmlns:tns="http://www.example.org/stackoverflow" elementFormDefault="qualified">
<complexType name="ParentType">
<sequence>
<element name="Child" type="tns:ChildType"
maxOccurs="unbounded" minOccurs="0">
</element>
</sequence>
<attribute name="id" type="string"></attribute>
</complexType>
<element name="Parent" type="tns:ParentType"></element>
<complexType name="ChildType">
<attribute name="id" type="string"></attribute>
<assert test="starts-with(#id,../#id)"/>
</complexType>
</schema>
I have several XSDs that reuse the same entities. For example, both the XSDs for the ProductPurchaseRequest.xsd and ProductQuoteRequest.xsd both have a <product> tag in them to describe the product in question. For this reason I created a Product.xsd file to define the <product> tag and both ProductPurchaseRequest.xsd and ProductQuoteRequest.xsd import the Product.xsd with a `.
I would like to use Castor to generate Java classes from theses XSDs, and for both of them to use the same class for representing the Product so that I could reuse the same logic for mapping them to our model's ProductModel class.
Can Castor do this? If so, what would be the Ant task syntax for it. If not, would perhaps JAXB be a better alternative?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
Can Castor do this? If so, what would be the Ant task syntax for it.
If not, would perhaps JAXB be a better alternative?
Below is an example of how this could be done using JAXB:
Product
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/Product"
xmlns:tns="http://www.example.org/Product"
elementFormDefault="qualified">
<element name="product">
<complexType>
<sequence>
<element name="id" type="string"/>
<element name="name" type="string"/>
</sequence>
</complexType>
</element>
</schema>
Since multiple XML schemas import Product.xsd we can leverage episode files so that the classes corresponding to Product.xsd are only generated once.
xjc -d out -episode product.episode Product.xsd
ProductPurchaseRequest.xsd
Below is an example of an XML schema that imports Product.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/ProductPurchaseRequest"
xmlns:tns="http://www.example.org/ProductPurchaseRequest"
xmlns:prod="http://www.example.org/Product"
elementFormDefault="qualified">
<import namespace="http://www.example.org/Product" schemaLocation="Product.xsd"/>
<element name="purchase-request">
<complexType>
<sequence>
<element ref="prod:product" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</schema>
When we generate classes from this XML schema we will reference the episode file we created when we generated Java classes from Product.xsd.
xjc -d out ProductPurchaseRequest.xsd -extension -b product.episode
ProductQuoteRequest.xsd
Below is another example of an XML schema that imports Product.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/ProductQuoteRequest"
xmlns:tns="http://www.example.org/ProductQuoteRequest"
xmlns:prod="http://www.example.org/Product"
elementFormDefault="qualified">
<import namespace="http://www.example.org/Product" schemaLocation="Product.xsd"/>
<element name="quote">
<complexType>
<sequence>
<element ref="prod:product"/>
</sequence>
</complexType>
</element>
</schema>
Again when we generate classes from this XML schema we will reference the episode file we created when we generated Java classes from Product.xsd.
xjc -d out ProductQuoteRequest.xsd -extension -b product.episode
For More Information
http://weblogs.java.net/blog/kohsuke/archive/2006/09/separate_compil.html
So I was able to get the whole thing working using the JAXB reference implementation. The trick was to realise that the download from JAXB site is a downloader and not the actual libraries! Double-click to accept the licence and the libraries will download locally. Created a test folder (JAXB_TEST) and copied all the downloaded .jars to a lib subfolder. I put all my XSDs in XSD subfolder. After that I ran the following Ant build.xml file.
<?xml version="1.0"?>
<project name="jaxb_test" basedir="." default="package" >
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
<classpath>
<fileset dir="./lib" includes="*.jar" />
</classpath>
</taskdef>
<target name="generate">
<delete dir="./gen-src" />
<mkdir dir="./gen-src" />
<xjc destdir="./gen-src" language="XMLSCHEMA" package="com.mmm" >
<schema dir="./xsd" includes="EPC*.xsd" />
</xjc>
</target>
<target name="compile" depends="generate" >
<delete dir="./bin" />
<mkdir dir="./bin" />
<javac srcdir="./gen-src" destdir="./bin" includeantruntime="false" />
</target>
<target name="package" depends="compile" >
<delete dir="./dist" />
<mkdir dir="./dist" />
<jar destfile="./dist/jaxb-gen.jar" basedir="./bin" />
</target>
</project>
The only problem I had was that I had an xsd with a root tag called <product> that anonymous extended the Product type to add a version attribute (which I always like to have on my root tag's) which was causing a name conflict for JAXB. So instead, I turned the anonymous type into a named type (i.e. TopLevelProduct) and set the root to that type and JAXB was happy with that.
I am using JAXB and can't figure out why my nested objects aren't being unmarshalled. I am generating the classes via the XJC command.
For example, when I unmarshall the Works object, the Composers collection always contains one Composer instance will a NULL name.
My XML looks like this:
<Works>
<Work>
<Composer>
<Name>Test Name</Name>
</Composer>
</Work>
</Works>
and XSD is like this:
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
jxb:version="2.0" xmlns:tns="http://www.example.org/test/"
targetNamespace="http://www.example.org/test/">
<element name="Works" type="tns:Work"></element>
<complexType name="Work">
<sequence>
<element name="Composers" type="tns:Composer" maxOccurs="unbounded"
minOccurs="1">
</element>
</sequence>
</complexType>
<complexType name="Composer">
<sequence>
<element name="Name" type="string">
</element>
</sequence>
</complexType>
And my code that does the unmarshalling:
JAXBContext jc = JAXBContext.newInstance("mypackagename");
Unmarshaller um = jc.createUnmarshaller();
Works works = (Works)um.unmarshal(new FileReader("src/main/resources/works.xml"));
Work work = works.getWorks().get(0);
Composer composer = work.getComposers().get(0);
System.out.println(composer.getName());
Name is always NULL, even though I know it has a value.
You could have an XML schema like:
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
jxb:version="2.0" xmlns:tns="http://www.example.org/test/"
targetNamespace="http://www.example.org/test/">
<element name="Works" type="tns:Works"></element>
<complexType name="Works">
<sequence>
<element name="Work" type="tns:Work" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="Work">
<sequence>
<element name="Composer" type="tns:Composer" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="Composer">
<sequence>
<element name="Name" type="string"/>
</sequence>
</complexType>
</schema>
That corresponds to the following XML:
<Works xmlns="http://www.example.org/test/">
<Work>
<Composer>
<Name>Test Name</Name>
</Composer>
</Work>
</Works>