【问题标题】:XML Schema: How to require at least one element B for every element A?XML Schema:如何要求每个元素 A 至少有一个元素 B?
【发布时间】:2018-06-16 01:17:03
【问题描述】:

我正在编写一个基于 XML 文件集合的 XML Schema 文件。我应该实现的一个要求是,对于每个元素 A,必须至少有一个元素 B 具有匹配的数据。

例如如果xml文件中有一个元素A是这样的:

<peanutButterCode>A001</peanutButterCode>

该文件中必须至少有一个匹配元素 B,如下所示:

<jellyCode>A001</jellyCode>

对如何实现这样的要求有任何想法,以使任何具有元素 A 而没有相应元素 B 的 xml 文件无法通过验证?

编辑:更具体地说,下面是一个简化的 XML 模式代码 sn-p,我将使用它来说明我的问题。它看起来很大,但这是我能做到的最小的。

目前,它确保对于 sr_cat_rel 中的每个 category_refservice_ref 元素,有对应的category_codeservice_code(位于configuration/categories/categoryconfiguration/service_requests/service_request)。这是通过 配置 下的 key/keyref 对来完成的。

我在实施时遇到困难的附加约束与我已经实施的相反;对于每个 category_codeservice_code ,必须至少有一个对应的 category_ref em>service_ref。我不能简单地添加反向键/键引用对,因为将 category_refservice_ref 作为键要求它们是唯一的.但是,它们不应该是,与 category_codeservice_code 不同。它们每个都可以单独sr_cat_rel元素中重复,但每个都是唯一的。这个警告以及语言中的愚蠢规则使我无法找到实现此约束的方法,这应该不是不可能的。

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://311selfserviceconfig.com" xmlns:tns="http://311selfserviceconfig.com" elementFormDefault="qualified">

        <element name="configuration" type="tns:configuration">
              <key name="categoryCodeKey">
                    <selector xpath="tns:categories/tns:category"/>
                    <field xpath="tns:category_code"/>
              </key>
              <key name="serviceCodeKey">
                    <selector xpath="tns:service_requests/tns:service_request"/>
                    <field xpath="tns:service_code"/>
              </key>
              <keyref name="categoryCodeKeyRef" refer="tns:categoryCodeKey">
                    <selector xpath="tns:service_request_category_relation/tns:sr_cat_rel"/>
                    <field xpath="tns:category_ref"/>
              </keyref>
              <keyref name="serviceCodeKeyRef" refer="tns:serviceCodeKey">
                    <selector xpath="tns:service_request_category_relation/tns:sr_cat_rel"/>
                    <field xpath="tns:service_ref"/>
              </keyref>
       </element>

       <complexType name="configuration">
              <sequence>
                     <element name="categories" type="tns:categories" maxOccurs="1" minOccurs="1"></element>
                     <element name="service_requests" type="tns:service_requests" maxOccurs="1" minOccurs="1"></element>
                     <element name="service_request_category_relation"
                           type="tns:service_request_category_relation" maxOccurs="1" minOccurs="1"></element>
              </sequence>
       </complexType>

       <complexType name="categories">
              <sequence>
                     <element name="category" type="tns:category" maxOccurs="unbounded" minOccurs="1"></element>
              </sequence>
       </complexType>

       <complexType name="category">
              <sequence>
                   <element name="category_code" type="string" maxOccurs="1" minOccurs="1"></element>
                     <!-- Irrelevant other child elements -->
              </sequence>
       </complexType>

       <complexType name="service_requests">
              <sequence>
                     <element name="service_request" type="tns:service_request" maxOccurs="unbounded" minOccurs="1"></element>
              </sequence>
       </complexType>

       <complexType name="service_request">
              <all>
                     <element name="service_code" type="string" maxOccurs="1" minOccurs="1"></element>
                     <!-- Misc other child elements -->
              </all>
       </complexType>

       <complexType name="service_request_category_relation">
              <sequence>
              <element name="sr_cat_rel" type="tns:sr_cat_rel" maxOccurs="unbounded" minOccurs="1"></element>
              </sequence>
       </complexType>

       <complexType name="sr_cat_rel">
              <sequence>
                     <element name="category_ref" type="string" maxOccurs="1" minOccurs="1"></element>
                     <element name="service_ref" type="string" maxOccurs="1" minOccurs="1"></element>
              </sequence>
       </complexType>
</schema>

【问题讨论】:

    标签: xml xsd schema xsd-validation


    【解决方案1】:

    您可以定义一个 key/keyref 对来确保每个 B 都有一个匹配的 A,并定义第二个 key/keyref 对来确保每个 A 都有一个匹配的 B。

    详细的代码取决于你没有告诉我们的结构细节。

    【讨论】:

    • 我刚刚在问题中添加了我的问题的更具体细节
    • 感谢您的 key/keyref 建议,它帮助我解决了一半的问题。但是在这种情况下,仅仅在另一个方向上再添加一对是行不通的,因为它暗示了它的唯一性。有关详细信息,请参阅我的编辑。
    • 根据您对需求的更详细说明,显然 XSD 1.0 无法实现这一点:它需要 XSD 1.1 断言。
    • 你能推荐一种方法来用断言做这样的事情吗?我对他们不熟悉。
    • 你可以写例如&lt;xs:assert test="every $a in .//a satisfies (some $b in .//b satisfies $a eq $b)"/&gt;
    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2015-03-25
    相关资源
    最近更新 更多