考虑以下(设计不佳?)XML文档:
<?xml version="1.0" ?>
<command_result>
<param name="protocol_version" value="3"/>
<param name="player_state" value="navigator"/>
</command_result>
我想要做的是创建一个XML架构(XSD格式),它根据value
属性的实际值指定name
属性的数据类型。
示例(伪代码):
if (param name = "protocol_version") then (param value type="xs:integer")
if (param name = "player_state") then (param value type="xs:string")
有没有办法在不修改源XML的情况下在模式文件中引入这样的条件语句?我已经查看了各种解决方案,但所有这些解决方案都需要以某种方式更改源(例如,设置xsi:type)。
修改
我目前的架构:
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="command_result">
<xs:complexType>
<xs:sequence>
<xs:element name="param" minOccurs="2" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<!-- the following line needs to be modified somehow -->
<xs:attribute name="value" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
答案 0 :(得分:2)
我不认为这是可能的。我能想到的唯一方法就是这样:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/schema"
xmlns:tns="http://www.example.org/schema" elementFormDefault="qualified">
<element name="command_result">
<complexType>
<sequence>
<choice>
<element name="param" type="tns:protocol_version_type" />
<element name="param" type="tns:player_state_type" />
</choice>
</sequence>
</complexType>
</element>
<complexType name="protocol_version_type">
<attribute name="name" type="string" fixed="protocol_version" />
<attribute name="value" type="integer" />
</complexType>
<complexType name="player_state_type">
<attribute name="name" type="string" fixed="player_state" />
<attribute name="value" type="string" />
</complexType>
</schema>
但显然这是不允许的。当我在Eclipse中验证此模式时,它会给我以下错误:
- cos-nonambig:“http://www.example.org/schema":param和”http://www.example.org/schema":param(或其替换组中的元素)违反了“Unique Particle”归因”。在针对此模式进行验证期间,将为这两个粒子创建歧义。
- cos-element-consistent:类型'#AnonType_command_result'的错误。 模型组中会显示名称为“param”且名称不同的多个元素。
如您所见,您不能拥有两个名称相同但类型不同的元素。但这正是您的XML所需要的。
编辑:您甚至无法定义更简单的架构:
<element name="command_result">
<complexType>
<sequence>
<element name="param" type="tns:proptocol_version_type" />
<element name="param" type="tns:type2" />
</sequence>
</complexType>
</element>
在此版本中,没有给出<choice>
,这意味着您的参数必须以给定的顺序出现。但是,虽然这会删除nonambig
错误,但element-consistent
错误仍然存在。
答案 1 :(得分:1)
如果您有权访问XSD 1.1验证程序,则可以使用条件类型分配根据param
属性的值为name
元素指定不同的绑定。 (您将绑定它的不同复杂类型主要区别在于为value
属性分配不同的类型。)
但总的来说,你是对的:为每个元素使用相同的元素名称是一种设计选择,它简化了一些事情,但代价是试图验证参数。