本文介绍了优先于组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的情况是存在一个我不拥有"的基本类型,它允许所有子元素都是可选的.从一般的业务角度来看,这是有道理的.例如,说是:

I have a situation where there is a base type that I don't "own" and it allows all child elements to be optional. From a general business perspective this makes sense. For example, say it was:

<xs:complexType name="BaseType">
    <xs:sequence>
        <xs:element name="id" type="xs:string" minOccurs="0"/>
        <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

此类型的实例将包含在我的流程使用的包含类型中.

An instance of this type will be contained in a containing type that my process uses.

<xs:complexType name="MyType">
    <xs:sequence>
        <xs:element name="Widget" type="BaseType"/>
        ...other stuff...
    <xs:sequence>
</xs:complexType>

但是,出于我的特定目的,我需要BaseType上的'id'元素始终存在.我当然可以在使用它的代码中强制执行此操作,但是有什么方法可以在xsd中表示它?

However, for my particular purposes, I need the 'id' element on a BaseType to be present always. I can enforce this in the code that consumes it, of course, but is there some way to represent this in the xsd?

编辑我忘了还有另一种类似的情况,我正在使用的元素在组中,而不是基本类型.

EDITI forgot one other. There's another, similar situation, where the elements I'm using are in a group rather than a base type.

<xs:group name="Address-Group">
    <xs:sequence>
        <xs:element name="street" type="xs:string" minOccurs="0"/>
        <xs:element name="city" type="xs:string" minOccurs="0"/>
        ...etc....
    </xs:sequence>
</xs:group>

如果我在MyType中使用其中之一,那么对于尝试覆盖诸如城市"之类的minOccurs,我会有相同的问题.

If I employ one of these in MyType, I'd have the same question about trying to override minOccurs for something like 'city'.

推荐答案

假设您确实总是说for my particular purposes, I need the 'id' element on a BaseType to be present always,那么您可以应用如下所示的重新定义:

Assuming that for my particular purposes, I need the 'id' element on a BaseType to be present always you really meant always, then you can apply a redefine such as the one below:

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSR Module (http://www.paschidev.com)-->
<xsd:schema xmlns="http://tempuri.org/XMLSchema.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:redefine schemaLocation="xsd-overriding-minoccurs-from-a-group.xsd">
        <xsd:complexType name="BaseType">
            <xsd:complexContent>
                <xsd:restriction base="BaseType">
                    <xsd:sequence>
                        <xsd:element name="id" type="xsd:string"/>
                        <xsd:element name="name" type="xsd:string" minOccurs="0"/>
                    </xsd:sequence>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
        <xsd:group name="Address-Group">
            <xsd:sequence>
                <xsd:element name="street" type="xsd:string"/>
                <xsd:element name="city" type="xsd:string" minOccurs="0"/>
            </xsd:sequence>
        </xsd:group>
    </xsd:redefine>
</xsd:schema>

问题是,总是"重新定义工作,即在所有使用BaseType的实例中,重定义的定义将优先.换句话说,在XSD中没有内置的机制可以让您选择上下文,除非您移至XSD 1.1,在那里您不需要重新定义,而是需要某种断言.问题是,我敢说XSD 1.1的支持程度甚至比XSD 1.0(跨平台,而不是在可能同时支持两者的特定平台(例如Saxon或Xerces)上)少.

The thing is, redefine works "always", i.e. in all instances where a BaseType is used, the redefined definition will take precedence. In other words, there is no mechanism built in XSD where you might be able to pick and choose your context, unless you move to XSD 1.1 where you wouldn't then need redefine but some sort of assertion. The problem is, I would venture to say that XSD 1.1 is even less supported than XSD 1.0 (across platforms rather than on a particular one that might happen to support both anyway, such as Saxon or Xerces).

这样的XML有效:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<paschidev.dummy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="BaseType" xmlns="http://tempuri.org/XMLSchema.xsd">
    <id>id1</id>
    <name>name1</name>
</paschidev.dummy>

这将失败:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<paschidev.dummy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="BaseType" xmlns="http://tempuri.org/XMLSchema.xsd">
    <name>name1</name>
</paschidev.dummy>

显示以下错误消息(基于.NET):

With the following error message (.NET based):

Error occurred while loading [], line 4 position 3
The element 'paschidev.dummy' in namespace 'http://tempuri.org/XMLSchema.xsd' has invalid child element 'name' in namespace 'http://tempuri.org/XMLSchema.xsd'. List of possible elements expected: 'id' in namespace 'http://tempuri.org/XMLSchema.xsd'.

或此(基于Java):

or this (Java based):

Error while loading [], line 4 position 8
cvc-complex-type.2.4.a: Invalid content was found starting with element 'name'. One of '{"http://tempuri.org/XMLSchema.xsd":id}' is expected.

重新定义可与支持XSD的XML处理器一起很好地工作.但是,某些XSD到代码的绑定框架或具有内置XSD支持的数据库引擎可能会对此产生影响.

The redefine works well with XSD-aware XML processors. However, some XSD to code binding frameworks, or database engines with built-in XSD support may cough on this one.

这篇关于优先于组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 03:24