How to use attribute value as discriminator to select polymorphic XML type?

I am trying to write an XML schema using an existing XML format description (i.e. a description of a form without a description of the elements in terms of multiplicity and element types). My last idea is to pass such an XSD to the code generator and get the binding classes.

Here is an example that I cannot handle:

packet1.xml:

<?xml version="1.0" ?> <packet kind="type1"> <field1>value1</field1> <field2>value2</field2> </packet> 

packet2.xml:

 <?xml version="1.0" ?> <packet kind="type2"> <field1>value3</field1> <field3>value4</field3> </packet> 

So, instead of the element name, the type is defined in the attribute value. type1 and type2 uniquely determine the type of package, i.e. type defines the set and types of nested fields.

My idea is to use polymorphic types in an XML sketch and XML Schema, as shown below:

schema.xsd:

 <?xml version="1.0"?> <xsd:schema> <xsd:complexType name="protocol_abstract" abstract="true"/> <xsd:element name="protocol" type="protocol_abstract"/> <xsd:complexType name="protocol_type1"/> <xsd:complexContent> <xsd:extension base="protocol_abstract"/> <xsd:sequence> <xsd:element name="field1" type="xsd:string"/> <xsd:element name="field2" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="kind" type="xsd:NMTOKEN" fixed="type1"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="protocol_type2"/> <xsd:complexContent> <xsd:extension base="protocol_abstract"/> <xsd:sequence> <xsd:element name="field1" type="xsd:string"/> <xsd:element name="field3" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="kind" type="xsd:NMTOKEN" fixed="type2"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:schema> 

This is almost a trick, but requires the xsi: type specification:

packet21.xml:

 <?xml version="1.0" ?> <packet kind="type1" xsi:kind="packet_type1"> <field1>value1</field1> <field2>value2</field2> </packet> 

packet22.xml:

 <?xml version="1.0" ?> <packet kind="type2" xsi:kind="packet_type2"> <field1>value3</field1> <field3>value4</field3> </packet> 

With this definition, the validator validates the XML. But, this is not very convenient, incoming messages do not contain xsi: type.

Is it possible to get rid of xsi: type and use only my kind attribute? Is there any other way to do this other than preprocessing? (convert attribute value to element name)

Thanks for any ideas in advance.

+3
source share
1 answer

Not. xsi:type is the only way to do this. In addition, the XML schema does not support conditional validation.

If you need further verification of such restrictions, you need to encode them or use something like Schematron.

+3
source

Source: https://habr.com/ru/post/1305142/


All Articles