Retain single root node definition while using derived elements substitution

rzoned3

New Member
In an XSD schema, you cannot declare an alement as the only valid root node for your document.
It's a PITA, but I'm aware about it.For ages I would simply do what is suggested in the linked answer -- only define \[code\]<simpleType>\[/code\]s and \[code\]<complexType>\[/code\]s, with the only \[code\]<element>\[/code\] defined at the global level being my desired root node.However, I'm currently up to a nice refactoring of my XSD/XSLT code base. One of the things I want to do is to restrict a certain element to only elements derived from a desired type, provided these derivatives can have different node names:\[code\]<xs:complexType name="parentType"> <xs:sequence> <xs:element ref="AChild" minOccurs="1" maxOccurs="unbounded" /> </xs:sequence></xs:complexType>\[/code\]where \[code\]AChild\[/code\] is an abstract base type from which other types will derive using \[code\]substitutionGroup\[/code\]:\[code\]<xs:complexType name="child_base" abstract="true"> ...</xs:complexType><xs:element name="AChild" type="child_base" abstract="true" />\[/code\]\[code\]<xs:element name="AConcreteChild" substitutionGroup="AChild" > <xs:complexType> <xs:complexContent> <xs:extension base="child_base"> ... </xs:extension> </xs:complexContent> </xs:complexType></xs:element><xs:element name="AnotherPossibleConcreteChild" substitutionGroup="AChild" > <xs:complexType> <xs:complexContent> <xs:extension base="child_base"> ... </xs:extension> </xs:complexContent> </xs:complexType></xs:element>\[/code\]The problem here is that the \[code\]substitutionGroup\[/code\] thing only works for elements declared at the global level. So now I have a bunch of previously internal \[code\]type\[/code\]s declared as global level \[code\]element\[/code\]s, and while that perfectly restricts the possible children for \[code\]parentType\[/code\], it also means the validation will succeed if any of the now-global children is provided as a root element, which I don't want.Options I have considered included:
  • Ditch the \[code\]substitutionGroup\[/code\] inheritance, move all the possible children to a separate namespace, and use \[code\]<xsd:any namespace="that namespace" />\[/code\]. Feels sort of okay, but I don't like the additional namespace and the worse-defined constraint.
  • Ignore the problem at the XSD level and check the root node name and namespace in the code that uses the XSD template. What I did not like here was breaking the separation of concerns, as in my design the XSD file was a black box for the calling code, and I would rather not introduce a hardcoded dependency on a node QName.
  • Quit refactoring and keep what I had before (and before I had all possible children manually listed in an \[code\]<xs:choice>\[/code\]).
My question is, is there any other way to make the any-derived-element constraint work without declaring multiple global-level \[code\]<element>\[/code\]s (so that the only-root-node constraint works again)?
 
Back
Top