XML 架构:我可以要求某些属性值但仍允许其他值吗? [英] XML Schema: Can I make some of an attribute's values be required but still allow other values?

查看:25
本文介绍了XML 架构:我可以要求某些属性值但仍允许其他值吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(注意:我无法更改收到的 XML 的结构.我只能更改验证方式.)

假设我可以得到这样的 XML:

Let's say I can get XML like this:

<Address Field="Street" Value="123 Main"/>
<Address Field="StreetPartTwo" Value="Unit B"/>
<Address Field="State" Value="CO"/>
<Address Field="Zip" Value="80020"/>
<Address Field="SomeOtherCrazyValue" Value="Foo"/>

我需要创建一个 XSD 架构来验证Street"、State"和Zip"必须存在.但我不在乎是否也出现了StreetPartTwo"和/或SomeOtherCrazyValue".

I need to create an XSD schema that validates that "Street", "State" and "Zip" must be present. But I don't care if either "StreetPartTwo" and/or "SomeOtherCrazyValue" happen to be present too.

如果我知道只有可以包含我关心的三个(并且每个只包含一次),我可以这样做:

<xs:element name="Address" type="addressType" maxOccurs="unbounded" minOccurs="3"/>

<xs:complexType name="addressType">
  <xs:attribute name="Field" use="required">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value="Street"/>
        <xs:enumeration value="State"/>
        <xs:enumeration value="Zip"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
</xs:complexType>

但这不适用于我的情况,因为我可能还会收到我不关心的其他地址元素(也具有字段"属性).

But this won't work with my case because I may also receive those other Address elements (that also have "Field" attributes) that I don't care about.

有什么想法可以确保我关心的东西存在但让其他东西也存在吗?

Any ideas how I can ensure the stuff I care about is present but let the other stuff in too?

TIA!肖恩

推荐答案

您无法仅使用 XML Schema 进行您所寻求的验证.

You cannot do the validation you seek, with just XML Schema.

根据 XML 架构第 1 部分:结构"规范...

当模型组的 {particles} 中直接或间接包含的两个或多个粒子具有相同命名的元素声明时作为它们的 {term},这些声明的类型定义必须是相同的.

When two or more particles contained directly or indirectly in the {particles} of a model group have identically named element declarations as their {term}, the type definitions of those declarations must be the same.

这并不是说您不能构建一个可以验证正确文档的架构.它的意思是,您不能构建一个无法在某些不正确的文档上进行验证的架构.当我说不正确"时,我的意思是违反您用英语陈述的限制的文件.

It's not to say that you cannot build a schema that will validate a correct document. What it means is, you cannot build a schema that will fail to validate on some incorrect documents. And when I say "incorrect", I mean documents that violate the constraints you stated in English.

例如,假设您有一个包含三个 Street 元素的文档,如下所示:

For example, suppose you have a document that includes three Street elements, like this:

<Address Field="Street" Value="123 Main"/> 
<Address Field="Street" Value="456 Main"/> 
<Address Field="Street" Value="789 Main"/> 
<Address Field="SomeOtherCrazyValue" Value="Foo"/> 

根据您的架构,该文档是有效地址.可以向架构添加 xs:unique 约束,以便它会拒绝这种损坏的文件.但即使使用 xs:unique,针对这样的模式进行验证也会声明其他一些不正确的文档是有效的——例如,具有三个

元素的文档,每个元素都有一个唯一的 Field 属性,但没有一个具有 Field="Zip".

According to your schema, that document is a valid address. It's possible to add a xs:unique constraint to your schema so that it would reject such broken documents. But even with a xs:unique, validating against such a schema would declare that some other incorrect documents are valid - for example a document with three <Address> elements, each of which has a unique Field attribute, but none of which has Field="Zip".

事实上,不可能生成正式编码您声明的约束的 W3C XML 模式.element almost 会让你陷入困境,但它只适用于元素,而不适用于属性.而且,它不能与扩展一起使用,因此在 W3C XML Schema 中,您不能说所有这些元素以任何顺序加上任何其他元素".

In fact it is not possible to produce a W3C XML Schema that formally codifies your stated constraints. The <xs:all> element almost gets you threre, but it applies only to elements, not to attributes. And, it cannot be used with an extension, so you can't say, in W3C XML Schema, "all these elements in any order, plus any other ones".

为了执行您寻求的验证,您的选择是:

In order to perform the validation you seek, your options are:

  1. 依赖于 XML Schema 以外的东西,
  2. 分多个步骤执行验证,第一步使用 XML Schema,第二步使用其他方法.

对于第一个选项,我认为您可以使用 Relax NG 来执行此操作.不利的一面是,它不是一个标准,据我所知,它既没有得到广泛支持,也没有得到发展.这就像学习盖尔语以表达思想一样.盖尔语没有任何问题,但它有点像语言上的死胡同,而且 我认为 RelaxNG 也是.

For the first option, I think you could use Relax NG to do it. The downside of that is, it's not a standard and as far as I can tell, it is neither widely supported nor growing. It would be like learning Gaelic in order to express a thought. There's nothing wrong with Gaelic, but it's sort of a linguistic cul-de-sac, and I think RelaxNG is, too.

对于第二个选项,一种方法是首先根据您的架构进行验证,然后作为第二步:

For the second option, an approach would be to validate against your schema as the first step, and then, as the second step:

A.应用 XSL 转换,将

元素转换为以其 Field 属性值命名的元素.该转换的输出将如下所示:

A. apply an XSL transform which would convert <Address> elements into elements named for the value of their Field attribute. The output of that transform would look like this:

<root>
  <Street Value="101 Bellavista Drive"/>
  <State  Value="Confusion"/>
  <Zip    Value="10101"/>
</root>

B.针对不同的模式验证该转换的输出,如下所示:

B. validate the output of that transform against a different schema, which looks something like this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
  <xs:element name="root">
    <xs:complexType>
      <xs:all>
        <xs:element maxOccurs="1" minOccurs="1" ref="Street" />
        <xs:element maxOccurs="1" minOccurs="1" ref="State" />
        <xs:element maxOccurs="1" minOccurs="1" ref="Zip" />
      </xs:all>
    </xs:complexType>
  </xs:element>

  <xs:element name="Street">
    <xs:complexType>
      <xs:attribute name="Value" use="required" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="State">
    <xs:complexType>
      <xs:attribute name="Value" use="required" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Zip">
    <xs:complexType>
      <xs:attribute name="Value" use="required" type="xs:string"/>
    </xs:complexType>
  </xs:element>

</xs:schema>

您需要扩展该架构以处理转换输出中的其他元素,例如 .或者,您可以将 xsl 转换结构化为不发出不是 {State,Street,Zip} 之一的元素.

You would need to extend that schema to handle other elements like <SomeOtherCrazyValue> in the output of the transform. Or you could structure the xsl transform to just not emit elements that are not one of {State,Street,Zip}.

澄清一下,我知道您无法更改收到的 XML.这种方法不需要那个.它只是使用时髦的两步验证方法.一旦第二个验证步骤完成,您就可以丢弃转换的结果.

Just to be clear, I understand that you cannot change the XML that you receive. This approach wouldn't require that. It just uses a funky 2-step validation approach. Once the 2nd validation step completes, you could discard the result of the transform.

编辑 - 实际上,肖恩,再想一想,您可以只使用步骤 B.假设您的 XSL 转换仅从文档中删除<;Address> 元素的 Field 属性值没有 State、Street 或 Zip.换句话说,不会有

.可以使用您的架构验证该转换的结果,使用 maxOccurs="3"、minOccurs="3" 和 xs:unique.

EDIT - Actually, Sean, thinking about this again, you could just use step B. Suppose your XSL transform just Removes from the document only <Address> elements that do not have State, Street or Zip for the Field attribute value. In other words, there would be no <Address Field="SomeOtherCrazyValue"...>. The result of that transform could be validated with your schema, using a maxOccurs="3", minOccurs="3", and an xs:unique.

这篇关于XML 架构:我可以要求某些属性值但仍允许其他值吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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