3

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?

jccampanero
  • 50,989
  • 3
  • 20
  • 49
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
  • It's a limitation. The unbounded group is translated to a `List` or `List>`. You have two such things, for which the code generation probably tries to create the same field and methods. In this case, removing the second occurrence doesn't change much; the only difference is that the `upnp:class.group` now must come at the end, where before it was allowed between members of the groups. – Rob Spoor Jun 07 '22 at 11:47
  • Thx, well it does change quite alot if the xml I receive does have group between the two lists as now my jaxb classes wont be valid to marshall in the data, but I havent seen an example of this so far so i was wondering if it was actually an error i the specification. – Paul Taylor Jun 07 '22 at 12:24
  • Nope, the specification is valid. – Rob Spoor Jun 07 '22 at 15:45
  • Possible workaround: apply first a XSL transformation which will rename some xml elements (avoiding thereby name clash), and then unmarshall the obtained XML to java classes using JAXB. Be aware you will also need two versions of the schema, the first one (the original) to validate received xml, and a second one (the modified) for xml->java generation... – TacheDeChoco Jun 08 '22 at 12:38

1 Answers1

2

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.

jccampanero
  • 50,989
  • 3
  • 20
  • 49