0

I currently have the following code that will validate a recursive structure. Each level can have any of the element names listed in the substitutionGroup.

<xsd:complexType name="Level1">
   <xsd:sequence>
       <xsd:element ref="Level2" minOccurs="0" maxOccurs="unbounded" />
   </xsd:sequence>
   <xsd:attribute name="nodeID" type="xsd:integer" use="required" />
   <xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>

<xsd:element name="Level2" type="Level1" />
<xsd:element name="Level3" substitutionGroup="Level2" />
<xsd:element name="Level4" substitutionGroup="Level3" />
<xsd:element name="Level5" substitutionGroup="Level4" />

The following code validates using this schema

<Level1 nodeID="3648" name="1" >
   <Level3 nodeID="3649" name="1.1" >
     <Level2 nodeID="3650" name="1.1.1" >
     </Level2 >
   </Level3 >
   <Level4 nodeID="3651" name="1.2" >
   </Level4 >
</Level1 >

I really want to be able to enforce that Level2 is always in Level1, etc, like the following:

<Level1 nodeID="3648" name="1" >
   <Level2 nodeID="3649" name="1.1" >
     <Level3 nodeID="3650" name="1.1.1" >
     </Level3 >
   </Level2 >
   <Level2 nodeID="3651" name="1.2" >
   </Level2 >
</Level1 >

Is this possible using a substitutionGroup? Or is this something simpler I am missing?

The goal is to validate against the same underlying complexType AND if possible have a list of valid element names in the XSD file.

The main constraint is that the user base wants different levels and level names. I'm trying to keep the structure as simple as possible for adding/removing levels and changing their names from use case to use case.

You could think of this as an indented document structure where each level can have a different name like Chapter, Section, Paragraph. Each person wants to name their sections differently and can more or less levels.

Thanks

knightgambit
  • 166
  • 1
  • 7

2 Answers2

0

First, your terminology needs some tweaking:

currently have the following code that will validate a recursive structure

That's not code, it is a schema for your XML data structure. So it is an 'XML Schema'. It does validate a recursive structure, but your target document structure is not actually recursive...more on that later.

The following code validates using this schema

...and that is data not code. It's in the form of an XML document.

Second, your XML document will definitely not validate using the XML Schema that you posted because the schema does not contain any element declaration for <Level1>.

However, I think I understand what you are trying to do. Your approach is clever, but it is never going to work because this is not what substitution groups are designed for.

You admit that each user is going to want different names for the different levels, so you will be forced to generate the schema for each customer. So why not generate the entire XSD?

If you want to ensure that every tag has the same two attributes then you could use an abstract base type that has those attributes. The generator could create a complex type extension for each named level. But if you are generating the entire XSD then it would be just as easy to generate the attributes along with everything else.

If you want to be a technical purist you could perform the schema generation using a text templating engine, or (if you're using Java) using the Eclipse EMF XSD library.

kimbert
  • 2,376
  • 1
  • 10
  • 20
  • Thanks for the terminology clarification. I will try to be more exact in the future. Level1 is complexType that all the substitutions eventually point to. When using a tool, like Liquid, the substitutions appear indented, however, they don't stop propagating so the parent isn't enforced. – knightgambit Mar 31 '20 at 00:04
  • I don't understand the generic comment "it is never going to work because that is not what substitution groups are designed for". I believe they are designed to replace the element name with a different name. I was just hoping to be able to enforce the 'parent' in the definition. When I said recursive, I meant it from the standpoint that the same rule, er xml schema complexType (Level1) is recursively used for multiple levels in the resulting document structure definition / validation. – knightgambit Mar 31 '20 at 00:04
  • I believe substitution groups and the associated mechanism of type extension were included to allow XML Schema to describe object-oriented structures. XML Schema was never intended for modelling XML formats where the tag names are not known in advance. I agree that your schema is recursive, but your actual customer XML formats are not - each customer format is a simple hierarchy of names. – kimbert Mar 31 '20 at 08:25
  • I have to agree with your statement about not knowing tag names in advance. Thanks for the feedback. I am going to take a look at creating a small service that can provide the functionality needed. – knightgambit Apr 01 '20 at 00:18
0

After a lot of research, I've come to the conclusion that this schema will work, but not the why I want it to.

The substitutionGroup logic will resolve the name to the next level, see that the new level is a substitionGroup and resolve again. The logic will keep doing this until the Level1 complexType is found. The document will then be validated to Level1, irrespective of the element name or parents - so long as it resolved.

This example is similar and leads me to believe this isn't possible

However, I'm still researching this concept. There is a sliver of hope

knightgambit
  • 166
  • 1
  • 7