0

我定义了 xml 模式,其中包含一个名为“字段”的元素和一个名为“复合字段”的扩展。它定义如下:

<xs:complexType name="field">
        <xs:sequence>
            <xs:element name="value" type="xs:string" />
        </xs:sequence>      
</xs:complexType>
<xs:complexType name="composite-Field">
        <xs:complexContent>
          <xs:extension base="field">
            <xs:sequence>
                    <xs:element name="length" type="xs:integer" />
                  </xs:sequence>
                </xs:extension>
        </xs:complexContent>
</xs:complexType>

为了在我的 XML 中使用它,必须是:

<field xsi:type="composite-Field">
  <value>enjoy</value>
  <length>30</length>
</field>

我不希望我的 XML 用户使用模式语法,例如xsi:type=..." "
因此我的问题是:有没有办法使 XML 的语法成为:

<composite-Field>
      <value>enjoy</value>
      <length>30</length>
</composite-Field>

所以元素的名称将暗示它的继承性并且不会强制用户添加类型属性

我试过这个:

<xs:element name="MyCompositeField" type="composite-field"/>

接着:

<MyCompositeField>
          <value>enjoy</value>
          <length>30</length>
</MyCompositeField>

但它也没有通过 XSD 架构验证


2010 年 9 月 12 日:作为对建议答案的回应,我稍微细化了我的问题。
架构如下所示:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 

    <xs:element name="general">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="field" type="field" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="field"> 
        <xs:sequence> 
            <xs:element name="value" type="xs:string" /> 
        </xs:sequence> 
    </xs:complexType> 



    <xs:complexType name="composite-Field" > 
        <xs:complexContent> 
            <xs:extension base="field" > 
                <xs:sequence> 
                    <xs:element name="length" type="xs:integer" /> 
                </xs:sequence> 
            </xs:extension> 
        </xs:complexContent> 
    </xs:complexType> 

    <xs:element name="MyCompositeField" type="composite-Field"/> 

</xs:schema> 

所需的 xml 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
 <general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
    <MyCompositeField> 
        <value>enjoy</value> 
        <length>30</length> 
    </MyCompositeField> 

 </general>

使用这种组合,我得到了错误消息的响应:

cvc-complex-type.2.4.a:发现以元素“MyCompositeField”开头的无效内容。需要“{field}”之一。

4

1 回答 1

1

您的问题更新表明真正的问题出在<general>元素中。一个有效的文件将是

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
    <field> 
        <value>enjoy</value> 
    </field> 
</general>

扩展类型“字段”不会修改原始类型。相反,它会创建一个基于旧“字段”类型的新类型。如果您想将<value><length>元素都作为元素的子项<field>,则应将<field>元素的类型从“字段”更改为“复合字段”。

<xs:element name="general">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="field" type="composite-Field" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

这验证了文件

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
    <field> 
        <value>enjoy</value> 
        <length>30</length> 
    </field> 
</general>

其他解决方案是更改<general>元素有子元素<MyCompositeField>而不是元素,<field>因为<MyCompositeField>已经有内容类型“复合字段”

<xs:element name="general">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="MyCompositeField" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

这将验证文件

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema2.xsd">
    <MyCompositeField>
        <value>enjoy</value>
        <length>30</length>
    </MyCompositeField>
</general>

2010-08-14 更新

原发帖人评论:

但我希望“通用”元素能够包含“字段”或“复合字段”。不要严格要求只有其中一种类型。

那么您真正的问题是您希望您的架构验证这两个文档吗?

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:noNamespaceSchemaLocation="schema2.xsd">
    <field> 
        <value>enjoy</value> 
    </field> 
</general>

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="schema2.xsd">
    <MyCompositeField>
        <value>enjoy</value>
        <length>30</length>
    </MyCompositeField>
</general>

在这种情况下,整个问题可以看作:

  1. “如何让一个元素有这些选择之一作为子元素?”
    或者因为您的类型几乎相似:
  2. “如何允许可选元素(可以不存在的元素)?”

如果您最初清楚地说明了您想要实现的目标/代码是什么以及您目前拥有哪些代码会导致您的问题,那么整个问题可能会更快地解决

对#1 的回答 用于允许<xs:choice>几个独立的子内容之一。

使用这种结构,您可以允许<general>拥有一个<field><MyCompositeField>子元素

<xs:element name="general">
    <xs:complexType>
        <xs:choice>
            <xs:element name="field" type="field" />
            <xs:element name="MyCompositeField" type="composite-Field" />
        </xs:choice>
    </xs:complexType>
</xs:element>

因此,您的架构中的这种更改将允许我在上面发布的两个文档。

回答 #2如果拥有 type 的唯一原因composite-Field是允许可选<length>元素,您可以轻松修改原始field类型并使用它而不是 typecomposite-Field

<xs:complexType name="field"> 
    <xs:sequence> 
        <xs:element name="value" type="xs:string" /> 
        <xs:element name="length" type="xs:integer" minOccurs="0" /> 
    </xs:sequence> 
</xs:complexType> 

此模式定义创建一个允许可选长度元素的类型,从而验证这两个文档

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="schema2.xsd">
    <field> 
        <value>enjoy</value> 
    </field> 
</general>

<?xml version="1.0" encoding="UTF-8"?>
<general xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="schema2.xsd">
    <field> 
        <value>enjoy</value> 
        <length>30</length> 
    </field> 
</general>
于 2010-09-07T16:44:13.090 回答