I'm trying to generate the java classes using JAXB for the below XSD.
And I had to use the below bindings file to generate enum classes for any simple element derived from xs:string and that has enumeration facets.
However it always generates a String instead...
(Note: I cannot change the XSD)
see typeSafeEnumBase here
bindings.xjb file:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:version="2.0">
<jaxb:globalBindings typesafeEnumMemberName="generateName" typesafeEnumBase="xs:string"/>
</jaxb:bindings>
test.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ElementName">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="MY_ENUM_1"/>
<xs:enumeration value="MY_ENUM_2"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element ref="ElementName"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
command:
xjc -verbose test.xsd -b bindings.xjb
Generated java class:
Root.java
You must add following bindings
<jaxb:bindings node="//xs:element[#name='ElementName']/xs:simpleType">
<jaxb:typesafeEnumClass name="ElementName" />
</jaxb:bindings>
Related
I am trying to understand <any> element in xsd. I had two xsds.
Book Catalogue.xsd
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="BookCatalogue">
<xs:complexType>
<xs:sequence>
<xs:element name="Book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string" />
<xs:element name="Author" type="xs:string" />
<xs:element name="Date" type="xs:string" />
<xs:element name="ISBN" type="xs:string" />
<xs:element name="Publisher" type="xs:string" />
<xs:any namespace="##any" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Reviewer.xsd
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="Reviewer">
<xs:complexType>
<xs:sequence>
<xs:element name="Name">
<xs:complexType>
<xs:sequence>
<xs:element name="First" type="xs:string" />
<xs:element name="Last" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
But if i validate the below xml based on above xsd, i am getting cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'p:Reviewer'. error. Does both xsd file should not be in same namespace?
<?xml version="1.0" encoding="UTF-8"?>
<pr:BookCatalogue xmlns:pr="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com AddRequest.xsd ">
<pr:Book>
<pr:Title>pr:Title</pr:Title>
<pr:Author>pr:Author</pr:Author>
<pr:Date>pr:Date</pr:Date>
<pr:ISBN>pr:ISBN</pr:ISBN>
<pr:Publisher>pr:Publisher</pr:Publisher>
<p:Reviewer xmlns:p="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com Children.xsd ">
<p:Name>
<p:First>p:First</p:First>
<p:Last>p:Last</p:Last>
</p:Name>
</p:Reviewer>
</pr:Book>
</pr:BookCatalogue>
Two options...
Option One: If you do not want to have to have the definition of p:Reviewer present, add processContents="lax" to your xs:any element:
<xs:any namespace="##any" minOccurs="0" processContents="lax"/>
Per XML Schema Part 0: Primer Second Edition:
The lax value of the processContents attribute instructs an XML
processor to validate the element content on a can-do basis: It will
validate elements and attributes for which it can obtain schema
information, but it will not signal errors for those it cannot obtain
any schema information.
See also XML Validation in Java: processContents=“lax” seems not to work correctly.
You should also carefully adjust your xsi:schemaLocation values to point to the actual filename of each XSD for each namespace in play. Here is your XML instance with the changes that I made:
<?xml version="1.0" encoding="UTF-8"?>
<pr:BookCatalogue
xmlns:pr="http://www.w3schools.com"
xmlns:p="http://www.w3schools.com/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com BookCatalogue.xsd http://www.w3schools.com/1 Reviewer.xsd">
<pr:Book>
<pr:Title>pr:Title</pr:Title>
<pr:Author>pr:Author</pr:Author>
<pr:Date>pr:Date</pr:Date>
<pr:ISBN>pr:ISBN</pr:ISBN>
<pr:Publisher>pr:Publisher</pr:Publisher>
<p:Reviewer>
<p:Name>
<p:First>p:First</p:First>
<p:Last>p:Last</p:Last>
</p:Name>
</p:Reviewer>
</pr:Book>
</pr:BookCatalogue>
Note: Make sure that the targetNamespace in Review.xsd matches what's declared for it in BookCatalogue.xml's xsi:schemaLocation attribute.
Option Two: If you do want to insist that the definition of p:Reviewer be present, just make the above changes to be sure that Review.xsd can be found per the xsi:schemaLocation mechanism. No processContents setting is required; it defaults to strict.
I'm trying to use the Simplify plugin to replace a complex property with a set of simpler ones. I made it working following the plugin's manual. But I can't change the original schema, so I have to use an external bindings.xjb. And it gives me all sort of errors. Does somebody have a working example of a similar thing?
Original XSD:
<xs:schema id="messages"
elementFormDefault="qualified"
version="Exchange2010_SP2"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.microsoft.com/exchange/services/2006/messages">
<xs:import namespace="http://schemas.microsoft.com/exchange/services/2006/types" schemaLocation="types.xsd"/>
...
<xs:complexType name="ArrayOfResponseMessagesType">
<xs:choice maxOccurs="unbounded">
<xs:element name="CreateItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
<xs:element name="DeleteItemResponseMessage" type="m:ResponseMessageType"/>
<xs:element name="GetItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
...
</xs:choice>
</xs:complexType>
Modified XSD that works for me:
<xs:schema id="messages"
elementFormDefault="qualified"
version="Exchange2010_SP2"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:extensionBindingPrefixes="simplify"
targetNamespace="http://schemas.microsoft.com/exchange/services/2006/messages">
<xs:import namespace="http://schemas.microsoft.com/exchange/services/2006/types" schemaLocation="types.xsd"/>
...
<xs:complexType name="ArrayOfResponseMessagesType">
<xs:choice maxOccurs="unbounded">
<xs:element name="CreateItemResponseMessage" type="m:ItemInfoResponseMessageType">
<xs:annotation>
<xs:appinfo>
<simplify:as-element-property/>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="DeleteItemResponseMessage" type="m:ResponseMessageType"/>
<xs:element name="GetItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
...
</xs:choice>
</xs:complexType>
My bindings.xjb (that I want to use instead of changing the schema):
<bindings version="2.1"
xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
extensionBindingPrefixes="simplify">
<bindings schemaLocation="../wsdl/messages.xsd" node="/xs:schema/xs:complexType[#name='ArrayOfResponseMessagesType']/xs:choice/xs:element[1]">
<xs:annotation>
<xs:appinfo>
<simplify:as-element-property/>
</xs:appinfo>
</xs:annotation>
</bindings>
</bindings>
My current exception
org.xml.sax.SAXParseException: Unsupported binding namespace "http://www.w3.org/2001/XMLSchema". Perhaps you meant "http://java.sun.com/xml/ns/jaxb/xjc"?
Ok, I figured this out. Here is the configuration that made it working:
<bindings version="2.1"
xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
extensionBindingPrefixes="simplify">
<bindings schemaLocation="../wsdl/messages.xsd" node="/xs:schema/xs:complexType[#name='ArrayOfResponseMessagesType']/xs:choice/xs:element[1]">
<simplify:as-element-property/>
</bindings>
</bindings>
That simple.
I use JAXB to generate Java classes from XSD, JAXB unable to identify the group element from included xsd, simple elements works fine. Error : org.xml.sax.SAXParseException: undefined simple or complex type
<?xml version="1.0" encoding="UTF-8"?>
<!-- Schema for itinerary response -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.cleartrip.com/air/" xmlns:air="http://www.cleartrip.com/air/">
<xs:include schemaLocation="air-common.xsd"/>
***<xs:element name="itinerary" type="air:TripType"/>***
</xs:schema>
air-common.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://www.cleartrip.com/air/"
xmlns:air="http://www.cleartrip.com/air/">
<xs:simpleType name="NameType">
<xs:annotation>
<xs:documentation>Defining a type for a name</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="27"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AirportCodeType">
<xs:annotation>
<xs:documentation>Airport codes</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z0-9]{3}"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="PhoneNumberType">
<xs:annotation>
<xs:documentation>Phone numbers</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
***<xs:group name="TripType">
<xs:annotation>
<xs:documentation>Trip type -- used to display an itinerary or trip</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element minOccurs="0" ref="air:trip-id"/>
<xs:element minOccurs="0" ref="air:created-at"/>
<xs:element ref="air:pricing-summary"/>
<xs:element ref="air:flights"/>
<xs:element ref="air:pax-pricing-info-list"/>
<xs:element ref="air:pax-info-list"/>
<xs:element ref="air:contact-detail"/>
<xs:group minOccurs="0" ref="air:PaymentDetailResponse"/>
<xs:element minOccurs="0" ref="air:ancillary-data"/>
</xs:sequence>
</xs:group>***
</xs:schema>
Code generation works fine with all simple type, problem is only with xs:group name="TripType", what might be the problem.
How do I get the jaxb:class element to show? I currently have the following xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:version="2.0" jaxb:extensionBindingPrefixes="xjc"
elementFormDefault="qualified" targetNamespace="***"
xmlns:common="***">
<xs:complexType name="IdentifiableDTO" abstract="true">
<xs:annotation>
<xs:appinfo></xs:appinfo>
</xs:annotation>
<xs:attribute name="id" type="common:uuid" />
</xs:complexType>
</xs:schema>
But the only elements I can access within the xs:appinfo is jaxb:globalBindings and jaxb:javaType. I need to specify the jaxb:class so I can add some custom behaviour.
What is exactly the problem with:
<xs:complexType name="IdentifiableDTO">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="MySpecificIdentifiableDTOClassName"/>
</xs:appinfo>
</xs:annotation>
<!-- ... -->
</xs:complexType>
What do you mean by "get the jaxb:class element to show?"
I have following XML schema:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="content" type="contentType"/>
<xs:complexType name="contentType">
<xs:complexContent>
<xs:extension base="versionedElementType">
<xs:sequence>
<xs:element name="item" type="itemType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="itemType" mixed="true">
<xs:complexContent>
<xs:extension base="itemTypeBase">
<xs:sequence>
<xs:element name="order" type="xs:unsignedInt"/>
<xs:element name="id" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- Simple type convert to complex type -->
<xs:complexType name="itemTypeBase" mixed="true">
<xs:simpleContent>
<xs:extension base="itemDescriptionType">
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Simple type -string restriction -->
<xs:simpleType name="itemDescriptionType" >
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="versionedElementType">
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
which I use to validate this XML instance (I want to mix the text in the 'item' element with sub-elements 'order' and 'id'):
<?xml version="1.0" encoding="UTF-8"?>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Content.xsd"
version ="1.0">
<item>Description here...
<order>2</order>
<id>2</id>
</item>
</content>
Whatever I did the validation still says taht there is an error:
The content type of a derived type and that of its base must both be mixed or both be element-only. Type 'itemType' is mixed, but its base type is not.
But I can see that both types - itemType and itemTypeBase are MIXED!!
Thanks a lot
STeN
First of all the error which I see if I open your schema in Visual Studio 2010 is:
The derived type and the based type
must have the same content type.
In you current schema the type itemTypeBase is defined with respect of the <xs:simpleContent> and derived type itemType with the respect of <xs:complexContent> which is not allowed. Either you allow no sub-elements and use <xs:simpleContent> or you do use child elements and use <xs:complexContent>.
I personally don't like and don't use mixed types. If I understand you correct you want to make some restrictions in the text from the content. You want to have the content length between 1 and 64 characters. But <order>2</order>, <id>2</id> and all whitespace, inclusive the new line characters, are also a part of the content. If you want that <item> has simple content, then you can not insert child elements inside.
So the pragmatical solution would be go away from the mixed model and use the XML document in the form
<?xml version="1.0" encoding="utf-8"?>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Content.xsd"
version ="1.0">
<item>
<description>Description here...</description>
<order>2</order>
<id>2</id>
</item>
</content>
where Content.xsd is
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="content" type="contentType"/>
<xs:complexType name="contentType">
<xs:sequence>
<xs:element name="item" type="itemType"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="itemType">
<xs:sequence>
<xs:element name="description" type="itemDescriptionType"/>
<xs:element name="order" type="xs:unsignedInt"/>
<xs:element name="id" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="itemDescriptionType" >
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
All will be very simple and clear.