开发者

How to use attribute value as a discriminator for XML polymorphic type selection?

开发者 https://www.devze.com 2022-12-21 11:42 出处:网络
I am trying to write XML Schema by existing XML format description (i.e. document - free form description of elements multiplicity and types). My final idea is to feed such XSD to code generator and g

I am trying to write XML Schema by existing XML format description (i.e. document - free form description of elements multiplicity and types). My final idea is to feed such XSD to code generator and get binding classes.

Here is an example I cannot cope with:

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 element name, type is defined in attribute value. type1 and type2 uniquely define type of packet, i.e. type defines set and types of nested fields.

My idea is to use polymorphic types in XML and XML Schema sketch is like the following:

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"/>
        &开发者_如何学运维lt;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 almost does the trick, but requires 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 such definition, validator confirms XML is correct. But, it's not very convenient, incoming messages don't contain xsi:type.

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

Thanks for any ideas in advance.


No. xsi:type is the only way to do this. Other than that, XML schema does not support conditional validation.

If you need further validation of such constraints, you need to code them or use something like Schematron.

0

精彩评论

暂无评论...
验证码 换一张
取 消