I have an XSD element
<xsd:element name="author" type="cmd:Author" nillable="true">
<xsd:annotation>
<xsd:documentation>Contains author name and author id
</xsd:documentation>
</xsd:annotation>
</xsd:element>
Type author:
<xsd:complexType name="Author">
<xsd:annotation>
<xsd:documentation>Author's name and id.
</xsd:documentation>
</xsd:annotation>
<xsd:simpleContent>
<xsd:extension base="cmd:AuthorName">
<xsd:attribute name="id" type="cmd:Id" use="optional">
<xsd:annotation>
<xsd:documentation>Author's Id
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
Base AuthorName:
<xsd:simpleType name="AuthorName">
<xsd:annotation>
<xsd:documentation>Type defining author's name.
It may contain characters from AllowedChars
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="cmd:AllowedChars">
<xsd:maxLength value="112"/>
</xsd:restriction>
</xsd:simpleType>
Type Id:
<xsd:simpleType name="Id">
<xsd:annotation>
<xsd:documentation>Id
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{6}"/>
</xsd:restriction>
</xsd:simpleType>
The problem is that I always have an ID but sometimes it may happen that AuthorName is null.
In that situation what I get is:
<author id="111111"/>
What I want to get is:
<author id="111111"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:nil="true"/>
My actual state makes problems with schema compatibility. Is it possible to do the thing I want without changing XSD model? Splitting Author into AuthorName and AuthorId isn't backward compatible and will require rewriting pretty big application.
Additional info (I'm not quite sure what is useful and what isn't): application is in J2E, I'm binding xsd with JAXB and I am generating classes using XJC.
Generated class Author:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Author", propOrder = {
"value"
})
public class Author implements Serializable
{
@XmlValue
protected String value;
@XmlAttribute(name = "id")
protected String id;
//getters and setters
}
You may need to provide more information regarding the implementation as well; most likely, that is what constrains you from getting what you need.
Spec wise, you're correct. The XSD spec is clear when stating that other XML attributes may appear in an element whose xsi:nil attribute has been set to true (the emphasis is mine).
The problem is that most binding technologies have not implemented this behaviour. For e.g., this article on MSDN clearly indicates your scenario as not supported by their standard XML serializer. This is an excerpt:
Conversely, it'll not be able to work the other way around, i.e. if any other attribute is set, it'll not be able to serialize an xsi:nil="true" attribute.
If you're doing this in house, there might be ways to adjust serializers to work the way you want - again, you need to provide more info. Otherwise, you should assume, as I've shown above, that there are platforms for which this is simply not going to work (out of the box).