2

考虑以下(设计不佳?)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>
4

2 回答 2

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(或它们的替换组中的元素)违反了“唯一粒子属性”。在针对此模式进行验证期间,将为这两个粒子创建歧义。
  • 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错误仍然存​​在。

于 2012-10-25T15:10:12.123 回答
1

如果您有权访问 XSD 1.1 验证器,则可以使用条件类型分配param根据其name属性的值为元素指定不同的绑定。(您将其绑定到的不同复杂类型在为value属性分配不同类型时会有所不同。)

但总的来说,您是对的:为每个元素使用相同的元素名称是一种简化某些事情的设计选择,但代价是您尝试验证参数。

于 2012-10-25T19:54:47.197 回答