integrating an xsd validator (lib or tool) - xsd

I am currently using a crossplatform c++ project (windows+linux) which will soon need an external xsd validator.
My plan is to:
either find a c++ library which does xsd validation (possibly a complex task)
or an existing tool which I could just launch as an external process (easier I believe; Xerces could be an option?)
I have a deep hierarchy of xsd files, so I need a solid tool for the job.
My question: I need some suggestions about some easy-to-integrate-yet-production-ready-solution.
My take for now is to use Xerces, the java version and just call it in a separate process.
Probably I need to wrap Xerces, since it seems to not allow xsd validation in the command line, directly, e.g. https://github.com/ndw/xjparse.
Thanks

You could use xmllint with the --schema option:
xmllint --noout --schema test.xsd test.xml
test.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="info" type="xs:string"/>
</xs:schema>
test.xml
<?xml version="1.0"?>
<info>abc</info>

Related

JAXBElements generated from wsdl in Mule

We have a wsdl that we want to use in Mule studio. We generated the Java classes through the CXF component. There are a lot of elements in the schemas that are like this :
<xs:element minOccurs="0" name="SortIndex" nillable="true" type="xs:string"/>
In the generated Java classes, we get them as JAXBElement which is not really nice as it is hard to work with those in the DataMapper. I saw that this behavior can be overriden by providing jaxb bindings. However, this is how our wsdl looks now:
<wsdl:portType name="ILegacy">
<jaxws:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="src\main\resources\Legacy.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<enableWrapperStyle>false</enableWrapperStyle>
<jaxb:globalBindings generateElementProperty="false"/>
</jaxws:bindings>
However, this doesnt change the generation of JAXBElements. Is there something wrong with this code?
Are you suing wsdl2java or xjc? or something else?
If you are using CXF wsdl2java or xjc pass in your binding file as a parameter to the command:
bindings123.xjb:
<jaxws:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="src\main\resources\Legacy.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<enableWrapperStyle>false</enableWrapperStyle>
<jaxb:globalBindings generateElementProperty="false"/>
</jaxws:bindings>
then use -b to pass the bindings file to jaxb:
xjc schema1.xsd schema2.xsd schema3.xsd -b bindings123.xjb

Using XJC to compile a XSD with mutiple schema

I have a XSD of the format:
<?xml version="1.0" encoding="utf-16"?>
<root>
<xs:schema --->
..
..
</xs:schema>
<xs:schema -->
..
..
</xs:schema -->
<xs:schema -->
..
..
</xs:schema -->
</root>
It gives an error when compiled using XJC compiler at line 1 "Content is not allowed in prolog".
If I change the encoding to , "ISO-8859-1"
it gives followwing error:
[ERROR] Unexpected <root> appears at line 2 column 10
line 2 of ****.xsd Failed to parse a schema.
If I remove the "root" tag, from the XSD, it starts giving the following error:
[ERROR] The markup in the document following the root element must be well-formed.
line 44 of file:****.xsd
Failed to parse a schema.
My question is whether we can use XJC to compile a XSD with more than 1 schema tag. I had tried this with following file format :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="abc" type="xs:string"/>
<xs:element name="cdf">
/xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
it worked perfectly well for the above , creating classes appropriately.
Does it has something to do with the namespace declaration?
In principle, the XSD spec allows multiple xs:schema elements to be included in the same XML document, so what you are trying to do is not unreasonable. In practice, a lot of XSD software (perhaps most XSD software) is not prepared for schema documents in which the xs:schema element is not the outermost element in the XML document, and even when software does support other cases, different programs don't always agree on how to behave.
See this Stack Overflow question for further discussion, including a passionate argument from a misinformed party that there is no XSD software at all that supports input of the kind you describe.
With XJC, your best option appears to be to put each xs:schema element in a separate XML document and use (a) a single driver file to import or include each of them in turn, or (b) to put them all in the same directory and hand XJC the name of the directory; it will scan the directory for schema files and compile them. You may also be able to do something with the -wsdl option.

Can JAXB handle multiple "root" elements?

I have a schema similar to the following...
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="t1" type="t1Type"/>
<xs:element name="t2" type="t2Type"/>
<xs:element name="t3" type="t3Type"/>
</xs:schema>
At first I thought this was an invalid schema but all the checks I do online validate it. This means the person supplying the XML can send any (or all) the types listed and still conform to the schema.
How do I go about mapping and unmarshalling all the different possibilities using JAXB?
I have no idea which of them I will be recieving.
You will need to leverage a factory class annotated with #XmlRegistry (usually called ObjectFactory). That class will contain a create method for each possible root element annotated with #XmlElementDecl. See this article I wrote for more details and examples.

JAXB - Creating modules for reuse

Does JAXB support modular code generation?
Most of my background is with JibX for XML marshalling, but for legacy reasons our firm is using JAXB.
One feature that was available for JIBX was modular code generation. Say I have a main schema but I have several different envelopes for that schema. With JibX I could create a jar file out of the JibX'ed core schema, and then in separate projects I could JibX my envelope schemas and simply point to the shared jar instead of having to duplicate the code generation of the core schemas for each envelope.
I don't yet see a way for JAXB to handle this - has anyone been successful doing something like this?
Thanks in advance,
Roy
For the JAXB RI, that's handled with "episode" files (these are really just customization files). Process the core schema first, making sure to have xjc use the -episode <file> arg. Package the results of that processing into a JAR file with the episode file in META-INF/sun-jaxb.episode. Then, pass that JAR file as an arg to xjc when processing the other schemas.
Using a JAXB 2.1 implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc), you can specify that schema types correspond to existing classes in order to prevent them from being generated.
For example:
root.xsd
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/root">
<xsd:import schemaLocation="imported.xsd" namespace="http://www.example.com/imported"/>
<xsd:complexType name="root">
<xsd:attribute name="root-prop" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
imported.xsd
<?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com/imported"
targetNamespace="http://www.example.com/imported">
<xsd:complexType name="imported">
<xsd:attribute name="imported-prop" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
Problem Statement
If you use the XJC tool to generate java classes from the XML schema:
xjc -d out root.xsd
You the following is generated:
com\example\imported\Imported.java
com\example\imported\ObjectFactory.java
com\example\imported\package-info.java
com\example\root\ObjectFactory.java
com\example\root\Root.java
com\example\root\package-info.java
imported-bindings.xml
You can use a JAXB bindings file to specify that types from imported.xsd point to existing classes:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jxb:bindings schemaLocation="imported.xsd">
<jxb:bindings node="//xs:complexType[#name='imported']">
<jxb:class ref="com.example.imported.Imported"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
Running the XJC
Now if we run XJC with out bindings file:
xjc -d out -b imported-bindings.xml root.xsd
None of the files specified in the bindings file will be generated:
com\example\root\ObjectFactory.java
com\example\root\Root.java
com\example\root\package-info.java
Alternative Approach
The code generated from the imported schema directly (xjc imported.xsd) and indirectly (xjc root.xsd) is the same. You can simply drop the code generated indirectly and point at the project containing the code that was generated directly.

How can I tell wsimport that separate WSDL files are referring to the same object classes?

I have three different JAX-WS services which use the same classes on the server (e.g. ServiceA, ServiceB, and ServiceC, all of which use MyCommonClass as a parameter). Another module we are developing is using wsimport to create a client for these services, however the problem is that wsimport creates separate instances of MyCommonClass for each service:
com.company.servicea.endpoint.MyCommonClass
com.company.serviceb.endpoint.MyCommonClass
etc.
I know that I could use the wsimport -p option to specify a common package for each endpoint, however I'd like to keep most of the classes in separate packages, but just to share certain common ones. From what I have read it sounds like a JAXB bindings file(s) might be able to help, but I haven't yet figured out the exact syntax to achieve the desired result. I think I'll need a separate bindings file for each service (as I call wsimport once for each one), which looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1" xmlns:tns="http://endpoint.servicea.company.com/">
<bindings node="//xsd:complexType[#name='myCommonClass']">
<class name="com.company.model.MyCommonClass"/>
</bindings>
</bindings>
Am I on the right track? Or do you have any alternative solutions to the problem?
Define your common classes in an xsd and import it in to the service WSDL's.
Then use the schema customization to generate definitions in this schema in to a separate package like "com.company.model"
<jxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="1.0">
<jxb:bindings schemaLocation="model.xsd" node="/xsd:schema">
<jxb:schemaBindings>
<jxb:package name="com.company.model"/>
</jxb:schemaBindings>
</jxb:bindings>
...
ref: http://jax-ws.java.net/jax-ws-21-ea1/docs/customizations.html#2.6_Class_Customization

Resources