uPnP defines a number of Xml schemas including didl-lite.xsd, including this section:
<xsd:sequence>
<xsd:element ref="dc:title"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:class.group"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
When I tried to build Java classes from this using jaxb it complained
Removing the second xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded" line so we have
<xsd:sequence>
<xsd:element ref="dc:title"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:class.group"/>
</xsd:sequence>
fixed the issue, and seems to make more sense.
But I am not clear is the Xsd actually invalid or is this just a limitation of generating Jaxb classes from Xsd?
I think both semantically and formally the schema provided is valid.
You can, for instance, verify the schema well-formedness with Java or online, for example, in this site.
The issue you are facing could be considered a kind of limitation of JAXB.
The limitation consists in that the generator encounters a value that has been already taken into consideration in the process of generating your classes, and it has a problem, because it will be unable to generate a property and the corresponding related methods and stuff for this second value because the names are already taken.
I will use the xjc
tool for code generation but the solution should be portable to the Maven or Gradle plugins too.
If you run the xjc
tool like this:
xjc -d out didl-lite-v2.xsd
the error description will give you a possible solution:
[ERROR] Property "AllowedUnderItem" is already defined. Use <jaxb:property> to resolve this conflict
The mentioned term <jaxb:property>
has to do with JAXB XML bindings.
JAXB XML bindings allows you to customize the JAXB Java classes generation process in different ways.
The necessary configuration is provided in a XML file with a certain information.
In this specific use case, you can define the following bindings XML file, let's name it binding.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="didl-lite-v2.xsd">
<jaxb:bindings
node="//xsd:complexType[@name='container.type']/xsd:sequence/xsd:group[@ref='didl-lite:allowed-under-container'][2]">
<jaxb:property name="allowedUnderContainerAfterUpnpClassGroup"/>
</jaxb:bindings>
<jaxb:bindings
node="//xsd:complexType[@name='item.type']/xsd:sequence/xsd:group[@ref='didl-lite:allowed-under-item'][2]">
<jaxb:property name="allowedUnderItemAfterUpnpClassGroup"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
As you can see, we are indicating that the second occurrence of the allowed-under-item
group
, represented by the XPath expression //xsd:complexType[@name='item.type']/xsd:sequence/xsd:group[@ref='didl-lite:allowed-under-item'][2]
, should be treated as allowedUnderItemAfterUpnpClassGroup
. We need to do something similar with allowed-under-container
.
Then, if you run again the xjc
tool passing in this XML bindings file, your classes will be generated successfully:
xjc -d out -b binding.xml didl-lite-v2.xsd
This or this other SO questions could be of help as well.