使用 XSD 对元素进行更清晰的扩展 [英] cleaner extension of elements using XSD

查看:29
本文介绍了使用 XSD 对元素进行更清晰的扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了 xml 架构,其中包含一个名为field"的元素和一个名为composite-field"的扩展.它的定义如下:

I defined xml schema the contains an element called 'field' and an extension to it called 'composite-field'. it is defined as following:

<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 中使用它必须是:

in order to use it in my XML ut has to be:

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

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

I don't want my XML users to use schema syntax such as xsi:type=..." "
Therefore my question is: Is there any way to make the syntax of the XML be:

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

因此元素的名称将暗示其继承性,并且不会强制用户添加类型属性??

我试过这个:

so the name of the element will imply its inheritence and wouldn't force the users add type attribute ??

I tried this:

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

然后:

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

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

but it also didn't pass the XSD schema validation

12/09/2010: 针对建议的答案,我稍微改进了我的问题.
架构如下所示:

12/09/2010: In response the suggested answer I refined my question a liitle bit.
The schema looks like that:

<?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 如下所示:

and the required xml looks like that:

<?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>

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

using this combination I get in response the error message:

cvc-complex-type.2.4.a:无效发现内容以元素MyCompositeField".之一应为{field}".

cvc-complex-type.2.4.a: Invalid content was found starting with element 'MyCompositeField'. One of '{field}' is expected.

推荐答案

您的问题更新表明真正的问题出在 元素中.一个有效的文件是

Your question update shows that the real problem is in the <general> element. A valid document would be

<?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>

扩展类型字段"不会修改原始类型.相反,它创建了一个基于旧字段"类型的新类型.如果你想让 元素作为 元素的子元素,你应该改变 元素的类型,从field"到composite-Field".

Extending the type "field" does not modify the original type. Instead it creates a new type that is based on the old "field" type. If you wanted to have both <value> and <length> elements as the chlidren of <field> element, you should change the type of the <field> element from "field" to "composite-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>

其他解决方案是将 元素更改为具有子元素 而不是元素 因为 已经有内容类型composite-Field"

Other solution would be to change the <general> element have child element <MyCompositeField> instead of element <field> since <MyCompositeField> already has content type "composite-Field"

<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

原海报评论:

但我希望general"元素能够包含field"或composite-field".不要严格要求只有其中一种类型.

But I want 'general' element to have the ability to contain either 'field' or 'composite-field'. Not to strict it to have ONLY one of those types.

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

So is your real problem is that you want your schema to validate both of these documents?

<?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>

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

In that case the whole question can be seen as:

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

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

The whole question could have been solved much faster if you had initially clearly stated what is your goal/code that you want to achieve and what code do you currently have that causes your problems

回答 #1 使用 允许多个独立子内容之一.

Answer to #1 Use <xs:choice> to allow one of several independent child contents.

使用此结构,您可以允许 具有 子元素

With this structure you can allow <general> to have either <field> or <MyCompositeField> child element

<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>

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

So this change in your schema would allow both of the documents I posted above.

回答 #2 如果使用 composite-Field 类型的唯一原因是允许可选的 元素,您可以只需轻松修改原始 field 类型并使用它代替 composite-Field

Answer to #2 If the only reason to have type composite-Field is to allow an optional <length> element you could just easily modify the original field type and use it instead of type composite-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> 

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

This schema definition creates a type that allows an optional length element and thus validates both of these documents

<?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>

这篇关于使用 XSD 对元素进行更清晰的扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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