I'm new to using xml, and having trouble figuring this out. I found a schema for the RSS spec online, and I can generate java classes from that self-contained schema using xjc
without issues.
I want to add fields from simpledc.xsd
because in RSS feeds, I'm seeing tags like dc:creator
on <items>
, and I'd like to set it up so code generation for that can work too. In my attempt, I added the xsd:include
for the dc
schema, and added a field to the item
definition.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- My addition -->
<xsd:include schemaLocation="simpledc.xsd" />
<xsd:element name="rss" type="rss" />
<xsd:complexType name="rss">
<xsd:sequence>
<xsd:element name="channel" type="channel" maxOccurs="1"
minOccurs="1" />
...
<xsd:complexType name="item">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" maxOccurs="1" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The title of the item.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
...
<!-- My addition -->
<xsd:element name="creator" type="dc:creator" maxOccurs="1" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
Intellij provides the error:
Cannot resolve symbol 'dc:creator'
And xjc
also provides a similar error:
$ xjc -p com.test.generated -d src/main/java/ src/main/resources/schemas/rss.xsd
parsing a schema...
[ERROR] s4s-att-invalid-value: Invalid attribute value for 'type' in element 'element'. Recorded reason: UndeclaredPrefix: Cannot resolve 'dc:creator' as a QName: the prefix 'dc' is not declared.
line 391 of file:/<project>/src/main/resources/schemas/rss.xsd
How do I set this up properly so that I can add elements with the dc
namespace in my xml schema, and have codegen work properly?
CodePudding user response:
Customizations to the default JAXB bindings are made in the form of binding declarations passed to the JAXB binding compiler, and can be made in two ways:
- As inline annotations in a source XML schema
- As declarations in an external binding customizations file
Inline Customizations
Customizations to JAXB bindings made by means of inline binding declarations in an XML schema file take the form of <xsd:appinfo>
elements embedded in schema <xsd:annotation>
elements (xsd
: is the XML schema namespace prefix). The general form for inline customizations is:
<xs:annotation>
<xs:appinfo>
.
.
binding declarations
.
.
</xs:appinfo>
</xs:annotation>
Customizations are applied at the location at which they are declared in the schema. For example, a declaration at the level of a particular element would apply to that element only. Note that the XMLSchema namespace prefix must be used with the <annotation>
and <appinfo>
declaration tags. In the example above, xs:
is used as the namespace prefix, so the declarations are tagged <xs:annotation>
and <xs:appinfo>
.
External Binding Customization Files
Customizations to JAXB bindings made by means of an external file containing binding declarations take the general form:
<jxb:bindings schemaLocation = "xs:anyURI">
<jxb:bindings node = "xs:string">*
<binding declaration>
<jxb:bindings>
</jxb:bindings>
schemaLocation
is a URI reference to the remote schemanode
is an XPath 1.0 expression that identifies the schema node withinschemaLocation
to which the given binding declaration is associated.
For example, the first schemaLocation/node
declaration in a JAXB binding declarations file specifies the schema name and the root schema node:
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
A subsequent schemaLocation/node
declaration, say for a simpleType
element named ZipCodeType
in the above schema, would take the form:
<jxb:bindings node="//xs:simpleType[@name='ZipCodeType']">
See the docs for more detail.
CodePudding user response:
I figured out how to do this. I used an include
where I should have used an import
because I was referencing a different namespace. And then for the element from the different namespace, I need to use a ref
to link to them:
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<xsd:import schemaLocation="dc.xsd" namespace="http://purl.org/dc/elements/1.1/"/>
...
<xsd:complexType name="item">
<xsd:sequence>
...
<!-- My addition -->
<xsd:element minOccurs="0" ref="dc:creator" />
</xsd:sequence>
</xsd:complexType>
I'm not sure what the intent of the simpledc.xsd
provided by the dublin core website. Using dc.xsd
seems to work for generating the schema.
Unfortunately, when you're trying to unmarshall xml according to this schema, it seems that the rss feed author needs to add xmlns
fields at the top level <rss>
element, and they mostly do not.