JAXB generated XSD validation error "Unique Particle Attribution" - java

I have a JAXB class, which has an element coming from another namespace. I would like to have an ANY element as well, which collects all the elements not described in the JAXB class. So I added a List<Object> annotated with the #XmlAnyElement.
I have generated an XSD from the JAXB class, but when I am validating I am getting an error: "cos-nonambig: "nb":b and WC[##other:""] (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles."
The JAXB class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType
public class Foo {
#XmlElement
String a;
#XmlElement(namespace="nb")
Bar b;
#XmlAnyElement
List<Object> other;
}
The XSD generated by JAXB
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:ns1="nb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="nb" schemaLocation="schema1.xsd"/>
<xs:complexType name="foo">
<xs:sequence>
<xs:element name="a" type="xs:string" minOccurs="0"/>
<xs:element ref="ns1:b" minOccurs="0"/>
<xs:any processContents="skip" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="bar">
<xs:sequence>
<xs:element name="bid" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="nb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="schema2.xsd"/>
<xs:element name="b" type="bar"/>
</xs:schema>
How should I add the XmlAnyElement to pass the validation?

Related

How to fix xmlMapper "Multiple fields representing property "PS"" issue with Jaxb?

I used Jaxb to generate a Jar file from xsd:
CustomObject inputRequest = xmlMapper.readValue(input, CustomObject.class);
The error message I am getting is:
com.fasterxml.jackson.databind.JsonMappingException: Multiple fields
representing property "PS": OrderLineType#pS vs OrderLineType#pSV5 at
[Source: (StringReader); line: 1, column: 1]
And my class is:
#XmlElement(name = "PS", namespace = "financetypes:defn:v4")
protected financetypes.v4.PSType pS;
#XmlElement(name = "PS", namespace = "financetypes:defn:v5")
protected financetypes.v5.PSType pSV5;
They have the same name, but different namespace.
Is xmlmapper able to handle XmlElement that has the same name and different namespace?
If yes, how do I fix this? If no, what should I do?
I am building jar file from jenkin. Is there a plugin that I can use to fix this issue?
Thanks!
here is my xsd
v4.xsd
<!--Begin Definition: Complex Type: PriceStructureType-->
<xs:complexType name="PriceStructureType">
<xs:sequence>
<xs:element name="PriceModel" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
Will be required in future...
TODO: Add valid items...
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="finance:SourceSystemPrice" minOccurs="0">
<xs:annotation>
<xs:documentation>
Will be required in future...
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="ComponentPrice" type="finance:ComponentListType" minOccurs="0">
<xs:annotation>
<xs:documentation>
Will be required in future...
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="PriceStructure" type="finance:PriceStructureType"/>
<!--End Definition: Complex Type: PriceStructureType-->
v5.xsd
<!--Begin Definition: Complex Type: PriceStructureType-->
<xs:complexType name="PriceStructureType">
<xs:sequence>
<xs:element name="PriceModel" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>
Will be required in future...
TODO: Add valid items...
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="finance:SourceSystemPrice" minOccurs="0">
<xs:annotation>
<xs:documentation>
Will be required in future...
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="ComponentPrice" type="finance:ComponentListType" minOccurs="0">
<xs:annotation>
<xs:documentation>
Will be required in future...
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:element name="PriceStructure" type="finance:PriceStructureType"/>
<!--End Definition: Complex Type: PriceStructureType-->
common.xsd
xmlns:finance="urn:financetypes:defn:v4"
xmlns:finance_v5="urn:financetypes:defn:v5"
<xs:import namespace="urn:financetypes:defn:v4" schemaLocation="financetypes.v4.xsd"/>
<xs:import namespace="urn:financetypes:defn:v5" schemaLocation="financetypes.v5.xsd"/>
<xs:choice>
<xs:element ref="finance:PriceStructure" minOccurs="0">
<xs:annotation>
<xs:documentation xml:lang="en">
Price Structure itemizes the price components of this OrderLine. Pricing
is a integral part of the Sales Order record.
This should be a required element for a sales order, but it is marked
as optional for backward compatibility.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="finance_v5:PriceStructure" minOccurs="0">
<xs:annotation>
<xs:documentation xml:lang="en">
Price Structure itemizes the price components of this OrderLine. Pricing
is a integral part of the Sales Order record.
This should be a required element for a sales order, but it is marked
as optional for backward compatibility.
</xs:documentation>
<xs:appinfo>
<jaxb:property name="PriceStructureV5"/>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:choice>
You could do this. For a root class containing these 2 elements:
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class Root {
#XmlElement(name = "PS", namespace = "financetypes:defn:v4")
protected financetypes.v4.PSType pS;
#XmlElement(name = "PS", namespace = "financetypes:defn:v5")
protected financetypes.v5.PSType pSV5;
}
You can create you classes with the different versions like this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "v4PS", namespace = "financetypes:defn:v4")
public class PSType {
#XmlValue
private String value;
}
and:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "v5PS", namespace = "financetypes:defn:v5")
public class PSType {
#XmlValue
private String value;
}
For a sample xml as below:
<root xmlns:v4="financetypes:defn:v4" xmlns:v5="financetypes:defn:v5">
<v4:PS>version 4</v4:PS>
<v5:PS>version 5</v5:PS>
</root>
You will be able to unmarshall properly.
Update to respond to the comment:
You use xsd to generate the classes. You did not provide the xsd so I will assume you are not allowed to. I created an xsd to generate the classes you show in your question. The namespace.xsd looks like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:v4="financetypes:defn:v4" xmlns:v5="financetypes:defn:v5">
<xs:element name="root">
<xs:complexType>
<xs:all>
<xs:element name="v4PSType" type="PSTypev4" />
<xs:element name="v5PSType" type="PSTypev5" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:complexType name="PSTypev4">
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="PSTypev5">
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:schema>
Then your bindings would be:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="xjc">
<jaxb:bindings schemaLocation="../xsd/namespaces.xsd">
<jaxb:bindings node="//xs:complexType[#name='PSTypev4']">
<annox:annotate target = "class">
<annox:annotate annox:class="javax.xml.bind.annotation.XmlType" name="v4PSType" namespace="financetypes:defn:v4" />
</annox:annotate>
</jaxb:bindings>
<jaxb:bindings node="//xs:complexType[#name='PSTypev5']">
<annox:annotate target = "class">
<annox:annotate annox:class="javax.xml.bind.annotation.XmlType" name="v5PSType" namespace="financetypes:defn:v5" />
</annox:annotate>
</jaxb:bindings>
<jaxb:bindings node="//xs:element[#name='root']//xs:complexType//xs:all//xs:element[#name='v5PSType']">
<annox:annotate target = "field">
<annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" name="PS" namespace="financetypes:defn:v5" />
</annox:annotate>
</jaxb:bindings>
<jaxb:bindings node="//xs:element[#name='root']//xs:complexType//xs:all//xs:element[#name='v4PSType']">
<annox:annotate target = "field">
<annox:annotate annox:class="javax.xml.bind.annotation.XmlElement" name="PS" namespace="financetypes:defn:v4" />
</annox:annotate>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
And then you would end up with classes as those in my answer.

s4s-att-invalid-value: Invalid attribute value for 'name' in element 'element'

XML
<ns2:Response xmlns:ns2="http://test.com/" Id="122212">
<Infos size="1">
<Info>
<name>test</name>
</Info>
</Infos>
</ns2:Response>
Generated XSD
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- XML Schema Generated from XML Document on Mon Feb 20 2017 23:20:03 GMT+0530 (India Standard Time) -->
<!-- with XmlGrid.net Free Online Service http://xmlgrid.net -->
<xs:element name="ns2:Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="xmlns:ns2" type="xs:string"></xs:attribute>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
Error
SAX Exception: s4s-att-invalid-value: Invalid attribute value for
'name' in element 'element'. Recorded reason:
cvc-datatype-valid.1.2.1: 'ns2:Response' is not a valid value for
'NCName'.
There are several changes required for your XML and XSD, including:
Change <xs:element name="ns2:Response"> to <xs:element
name="Response"> because element name declarations must be
non-colonized names (NCNAMEs).
Delete <xs:attribute name="xmlns:ns2".../> because namespaces
cannot be declared as attributes.
Add a targetNamespace to the XSD that matches the namespace of the root element in the XML document.
Import a separate XSD for those elements that you wish to be in no namespace (given that your root elements is in a namespace). You must use a separate XSD to accomplish this.
Altogether, your XML,
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:ns2="http://test.com/"
Id="122212">
<Infos size="1">
<Info>
<name>test</name>
</Info>
</Infos>
</ns2:Response>
will validate successfully against these XSD:
Main
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
xmlns:ns="http://test.com/"
targetNamespace="http://test.com/">
<xs:import schemaLocation="Infos.xsd"/>
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element ref="Infos"/>
</xs:sequence>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Imported (Infos.xsd)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
I was able to get a parsed file by, as the above answer suggests, adding a target namepsace to the schema and by adding the ns prefix to all elements.
<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://test.com testq1.xsd" xmlns:ns2="http://test.com" Id="122212">
<ns2:Infos size="1">
<ns2:Info>
<ns2:name>test</ns2:name>
</ns2:Info>
</ns2:Infos>
and the schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://test.com"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element name="Info">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:int"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
You can approach this in 2 ways.
Approach 1 - multiple schemas
The more typical approach is to have a schema one for each namespace used.
So you end up with schemas that look like this
SampleXml0.xsd
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
<xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="C:\Temp\StackOverflow\42351409\SampleXml1.xsd" />
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="Infos" />
</xs:sequence>
<xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
SampleXml1.xsd
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Infos">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="Info">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:unsignedByte" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
Approach 2 - changing elementFormDefault
Now this is quite specific to your example, but as its only the root element that is qualified with a namespace its possible to change elementFormDefault to unqualified. This has the effect of forcing the elements defined as root element in the schema to have a namespace qualification, while the other elements do not.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2017 (https://www.liquid-technologies.com)-->
<xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Response">
<xs:complexType>
<xs:sequence>
<xs:element name="Infos" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Info" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="size" type="xs:unsignedByte" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
</xs:complexType>
</xs:element>
</xs:schema>
I would probably recommend creating multiple schemas as elementformdefault is typically overlooked by client implementations and ignored.
Why three <xs:sequence> elements? do you really need that? Could you explain better how your code is organized? Usually it is pretty simple, like this:
<xsd:element name="ns2:Response">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xs:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

Shared class for child element in JAXB in different xmls/roots

In JAXB when using automatic class generation via xjc from xsd scheme.
alpha.xsd
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="alpha">
<xs:complexType>
<xs:sequence>
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element name="person" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
beta.xml
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="country">
<xs:complexType>
<xs:sequence>
<xs:element name="class">
<xs:complexType>
<xs:sequence>
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As you can see there is Person element which is shared among these two schemes. What I would like to do is:
generate classes using xjc in a way that ObjectFactory class is shared for both schema classes (the output classes will be in one package)
not use nested static classes (with attribute localScoping="toplevel")
use Person class to bind with /alpha/persons/person as with /country/class/person so there are not two Person classes created
The purpose of this is unmarshalling one xml, applying business logic and creating another one as output where some elements (like Person) are same and shared for both xml files. The namespace will be the same for both files.
I would welcome if you can present me with complete .xjb bindings settings file. So far mine contains only:
<jxb:bindings version="1.0"
xmlns:jxb="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"
jxb:extensionBindingPrefixes="xjc">
<jxb:globalBindings localScoping="toplevel"/>
</jxb:bindings>
And of course I get name collision error as I do not know how to set binding compiler to see Person as the same entity/element.
You can use an external binding file to indicate that during class generation we wish to use our existing class for the complex type called Document.
binding.xml
<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="beta.xsd">
<jxb:bindings node="//xs:element[#name='person']/complexType">
<jxb:class ref="alpha.Person"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
XJC Call
xjc -b binding.xml beta.xsd
If namespace of person from A will be equals namespace person from B, that xjc has to generate the correct classes.

Error: Invalid content was found starting with element 'X'. One of '{X}' is expected

I'm trying to validate a simple XML using a simple XSD, but always get this error:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'linux'. One of '{linux}' is expected.
Why? The tag 'linux' is found and is one of {linux}!
java code:
public static void main(String[] args) {
try {
InputStream xml = new FileInputStream("data/test.xml");
InputStream xsd = new FileInputStream("data/test.xsd");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource(xsd));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(xml));
log.info("OK!");
} catch (Exception e) {
log.error(":(");
log.error(e.getMessage());
}
}
data/test.xml:
<?xml version="1.0" encoding="utf-8"?>
<so xmlns="http://test/">
<linux>
<debian>true</debian>
<fedora>true</fedora>
</linux>
</so>
data/test.xsd
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="http://test/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="so">
<xs:complexType>
<xs:sequence>
<xs:element name="linux">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:any processContents="lax" maxOccurs="unbounded"/>
</xs:sequence></xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Because the schema does not specify elementFormDefault="qualified", the local element declaration of element "linux" is declaring an element in no namespace, but the instance has a linux element in namespace "http://test/". The error message is confusing because it fails to make clear that the problem is with the namespace.
Dudytz, your <xs:any /> is not correct. The document cannot be validated, because the validator needs to be instructed how to validate the document. If you don't want that, you can specifiy for the <xs:any> a processContents attribute. If you set this to "lax" or "skip", it will work.
In short: replace <xs:any> with <xs:any processContents="lax" />
Update: We have changed your XSD to a working version:
<xs:schema xmlns="http://test/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test/">
<xs:element name="so">
<xs:complexType>
<xs:sequence>
<xs:element ref="linux"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="linux">
<xs:complexType>
<xs:sequence>
<xs:any processContents="lax" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

Create Login System with JAXB and EclipseLink

I want to create an XML schema that contains
<root>
<login>
<username> </username>
<paswword> </paswword>
</login>
</root>
How can i read this values and use them for authentication, with or without JAXB.
Here is the XML schema of your document:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="paswword" type="xs:string"/>
<xs:element name="username" type="xs:string"/>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="login"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="login">
<xs:complexType>
<xs:sequence>
<xs:element ref="username"/>
<xs:element ref="paswword"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Give that schema to some king of script that you are using to generate JAXB objects, pack them into a jar, put it into your classpath and use for your any purposes.

Categories