如何使用属性值作为XML多态类型选择的鉴别器? [英] How to use attribute value as a discriminator for XML polymorphic type selection?

查看:124
本文介绍了如何使用属性值作为XML多态类型选择的鉴别器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过现有的XML格式描述(即元素多样性和类型的无文档形式描述)来编写XML模式。我的最后一个想法是将这样的XSD提供给代码生成器并获得绑定类。



这里是一个我无法应对的例子:



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>

因此,类型在属性值中定义,而不是元素名称。 type1 type2 唯一地定义了数据包的类型,即类型定义了嵌套字段的集合和类型。



我的想法是使用XML中的多态类型和XML模式草图如下:



schema.xsd:

 <?xml version =1.0?> 
< xsd:schema>
< xsd:complexType name =protocol_abstractabstract =true/>
< xsd:element name =protocoltype =protocol_abstract/>

< xsd:complexType name =protocol_type1/>
< xsd:complexContent>
< xsd:extension base =protocol_abstract/>
< xsd:sequence>
< xsd:element name =field1type =xsd:string/>
< xsd:element name =field2type =xsd:string/>
< / xsd:sequence>
< xsd:attribute name =kindtype =xsd:NMTOKENfixed =type1/>
< / xsd:extension>
< / xsd:complexContent>
< / xsd:complexType>

< xsd:complexType name =protocol_type2/>
< xsd:complexContent>
< xsd:extension base =protocol_abstract/>
< xsd:sequence>
< xsd:element name =field1type =xsd:string/>
< xsd:element name =field3type =xsd:string/>
< / xsd:sequence>
< xsd:attribute name =kindtype =xsd:NMTOKENfixed =type2/>
< / xsd:extension>
< / xsd:complexContent>
< / xsd:complexType>
< / xsd:schema>

这几乎是诀窍,但需要xsi:type specification:



packet21.xml:

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

packet22.xml:

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

通过这样的定义,验证器确认XML是正确的。但是,这不是很方便,传入的邮件不包含xsi:type。



是否可以摆脱xsi:type,只使用我的 kind 属性?
除了预处理,还有其他方法吗? (将属性值转换为元素名称)



感谢您提前了解任何想法。

解决方案

不。 xsi:type 是唯一的方法。除此之外,XML模式不支持条件验证。



如果您需要进一步验证此类约束,则需要对其进行编码或使用像Schematron这样的东西。 >

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"/>
        <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.

这篇关于如何使用属性值作为XML多态类型选择的鉴别器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆