how to add static property in XSD file - xsd

I have one Java interface for example as following
public interface A
public static final String SD_A= "SD-A";
My question is how write the above property in XSD file ? Because I have blaze advisor project where I used XML BOM getting error that- A is not defined in current scope. So when I am adding that interface as following
I am getting error like :- is not a constant or static property defined by 'A'
Any suggestion to resolve the issue?

If I got you right, you want to add a static field to your schema-derived classes.
The simplest thing you can do is to use the code injector plugin:
Inserting code with XJC+xsd+jxb using the options " -Xinject-code -extension "
Something like:
<jxb:bindings schemaLocation="schema.xsd">
<jxb:bindings node="/xs:schema/xs:complexType[#name='SomeExtension']">
<ci:code>
public static final String EXTENSION_CODE = "NAMEOFTHEEXTENSION";
</ci:code>
</jxb:bindings>
</jxb:bindings>

I have created XSD file through eclipse i.e File->New->Other->JAXB->Scema from JAXB Classes
from Java application of Java classes. But now I required to make a XSD of Java interface. so when I am following the above process to create a XSD it is showing error "
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
com.test.IClassproduct is an interface, and JAXB can't handle interfaces.
So I have added that interface in another XSD file as below format
<xs:complexType name="IClassProducts"> <xs:sequence> <xs:element name="AHS" type="static" fixed="AHS" /> </xs:sequence> </xs:complexType>
But now it is showing error
'AHS' is not a constant or static property defined by 'IClassProducts'
so you have suggested to use below format .
<jxb:bindings schemaLocation="schema.xsd">
<jxb:bindings node="/xs:schema/xs:complexType[#name='SomeExtension']">
<ci:code>
public static final String EXTENSION_CODE = "NAMEOFTHEEXTENSION";
</ci:code>
</jxb:bindings>
</jxb:bindings>
My question is where I will add this and how to use . My purpose is anyhow I have use the above static property 'AHS' in XSD file So that when I will load that XSD file it can identify that property and can resolve the below error
'AHS' is not a constant or static property defined by 'IClassProducts'

Related

Generating JAXB classes for XML having same parent tag

I am getting xml input where parent tag is same but other tags are different.
every parent tag has attribute type which tells what content you should read.
i have created jaxb classes under different packages based on xml content ,
now problem is as parent class name is same for all ,so while making instance of JAXBContext ,which parent class should i passed ?
while marshelling we can specify if this is my tag then renamed to abc tag by passing annotation {name="abc"} , in same fashion what if i changed parent class name and based on annotation jaxb will unmarshel the xml
I got answer of this. i used binding file. where we can mentioned what should be name of generated class for particular tag.
<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="attribute.xsd">
<jxb:bindings node="//xs:element[#name='component']">
<jxb:class name="MyOwnClass"/>
</jxb:bindings>
</jxb:bindings>

Is there a way to ignore empty nodes in JAXB bindings file?

I am trying to create a generic .xjb bindings file to provide consistent Java classes generation from WSDLs / XSDs across multiple projects.
We generate the code via maven-jaxb2-plugin (Made by #lexicore).
The problem lies in the multiple projects part. If a particular binding instruction matches nothing in the provided XSD or WSDL, the class generation fails with
XPath evaluation of "<some_xpath_expression>" results in empty target node
How can I tell JAXB to ignore these cases so the bindings file can be used on any project without fine-tuning, regardless of the elements types used?
Here is a (stripped down) version showcasing the problem I have:
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="path/to/the/schema" node="/xs:schema">
<jxb:bindings multiple="true" node="//*[#type='xs:dateTime']">
<xjc:javaType name="java.time.LocalDateTime" adapter="a.b.c.LocalDateTimeAdapter" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
If I try to generate classes from a schema with no dateTime element, it will fail.
The objective is, in the end, to create something all projects of various teams could reuse without changing anything but the schemaLocation.
You need to set the required="no" attribute on the binding that you would like to allow not to match any node, i.e.
<jxb:bindings required="no" multiple="true" node="//*[#type='xs:dateTime']">
Depending on your context you may choose to say required="false" or required="0" as well.

How do I change the case of XSD element name when generated as #XmlElement via xjc

I have a schema where element names are defined in PascalCase eg:
<xsd:element name="EmployeeName" minOccurs="0" maxOccurs="1">
But I would like this to generate as:
#XmlElement(name = "employeeName")
I know this sounds slightly strange but it will then allow me to use Jackson JAXB annotation support to have my JSON generated in camelCase.
Is this possible?
Yes, it is possible to change the XML element name to (nearly) whatever you want by way of the annotation directives.
In this example, "price" is renamed to "itemprice". Java is not case insensitive, so your camel casing will be honored.
//Example: Code fragment
public class USPrice {
#XmlElement(name="itemprice")
public java.math.BigDecimal price;
}
<!-- Example: Local XML Schema element -->
<xs:complexType name="USPrice"/>
<xs:sequence>
<xs:element name="itemprice" type="xs:decimal" minOccurs="0"/>
</sequence>
</xs:complexType>
This example comes from the JAXB javadocs.
Note that JAXB support has a few "how to use it" workflows, "XSD to generate supporting Java classes", and "Java classes to generate an XSD". I prefer the latter, but you may be using the former. If you are, then you need to alter your XSD to have camelCase element names there.
There is no "use my XSD to generate Java classes, but with some overrides" workflow. Perhaps that's where the confusion comes from. Likewise, there is no "Use Java class annotations to generated XSD documents, but with some overrides". What you specify is going to be what you get, name-wise.

JAXB Marshalling - extending an existing class

I am in need of creating a series of Java objects via XML using JAXB that all extend a common base class that is already created (not using JAXB). For example, let's say I have following JAXB classes that I am trying to generate:
Penguin.xml -> Penguin.java
Robin.xml -> Robin.java
Cardinal.xml -> Cardinal.java
I already have an existing base class called Bird.java that I wish the three classes above to extend.
What is the best way to do this?
Thanks for your help!
That is very simple: you need to to create a JAXB binding file with following contents:
<jaxb:bindings version="1.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
>
<jaxb:globalBindings>
<!-- All beans should extend this base class: -->
<xjc:superClass name="org.mycompany.common.Bird" />
</jaxb:globalBindings>
</jaxb:bindings>
More information on this option (and other sweet things) you can find here.

Using dom4j DOMDocument to feed validator.validate(DOMSource) fails in java 1.6 (xsi:noNamespaceSchemaLocation is not allowed), works in 1.5

Using dom4j DOMDocument to feed validator.validate(DOMSource) fails in java 1.6 (with xsi:noNamespaceSchemaLocation is not allowed to appear in root element), works in 1.5
I'm finding the following problem quite intractable (OK, that's an understatement) - any insights will be appreciated. Currently it seems like the best idea is to drop dom4j in favour of e.g. XOM (http://stackoverflow.com/questions/831865/what-java-xml-library-do-you-recommend-to-replace-dom4j).
I've been validating in memory XML created from dom4j 'new DOMDocument()' - but this will not work with Java 6.
The following call to validate(source) of a dom4j (1.6.1) DOMDocument derived DOMSource works with Java 1.5.x but fails with Java 1.6.x:
public void validate() throws Exception {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setErrorHandler(null);
Schema schemaXSD = schemaFactory.newSchema(new URL(getSchemaURLString()));
Validator validator = schemaXSD.newValidator();
DOMSource source = new DOMSource(getDocument());
validator.validate(source);
}
getSchemaURLString() is also used to add the xsi:noNamespaceSchemaLocation attribute to the root node, i.e.:
xsi:noNamespaceSchemaLocation="http://localhost:8080/integration/xsd/fqlResponseSchema-2.0.xsd"
The exception follows:
Exception: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'xsi:noNamespaceSchemaLocation' is not allowed to appear in element 'specialfields'.;
complex-type.3.2.2: Attribute 'xsi:noNamespaceSchemaLocation' is not allowed to appear in element 'specialfields'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:417)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3182)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processAttributes(XMLSchemaValidator.java:2659)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:2066)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:705)
at com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.beginNode(DOMValidatorHelper.java:273)
at com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:240)
at com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:186)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:104)
at javax.xml.validation.Validator.validate(Validator.java:127)
Here's the start of the XML - generated after disabling the call to validator.validate(source):
<?xml version="1.0" encoding="utf-8"?>
<meetings xsi:noNamespaceSchemaLocation="http://localhost:8080/integration/xsd/fqlResponseSchema-2.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
.............
</meetings>
And of the XSD:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="meetings">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="summary" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="meeting" />
</xs:sequence>
<xs:element ref="error" />
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="summary">
................
So my root element is being rejected because it contains a xsi:noNamespaceSchemaLocation attribute. And the schema itself does not specify that as a valid attribute of my root element?
At this point it seems to me that I need to give up on dom4j for this task and switch to one of the other solutions, for example as outlined here:
But I'd like to know what I've done wrong at any rate!
Thanks in advance.
I had the same issue, and I found the following documentation at
http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi/index.html
Validate against a document-specified schema
Some documents specify the schema they expect to be validated against,
typically using xsi:noNamespaceSchemaLocation and/or
xsi:schemaLocation attributes like this:
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
...
If you create a schema without specifying a URL, file, or source, then
the Java language creates one that looks in the document being
validated to find the schema it should use. For example:
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
However, normally this isn't what you want. Usually the document
consumer should choose the schema, not the document producer.
Furthermore, this approach works only for XSD. All other schema
languages require an explicitly specified schema location.
The reason seems to be that non-namespace aware JAXP SAXParser is being created and used (see Link).
And solution for different libs I found at www.edankert.com.

Resources