XML 架构:我可以使某些属性的值成为必需的,但仍允许使用其他值吗?

2024-06-07

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

假设我可以像这样获取 XML:

<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 架构来验证“街道”、“州”和“邮政编码”must出席。但我不在乎“StreetPartTwo”和/或“SomeOtherCrazyValue”是否也恰好存在。

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

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

但这不适用于我的情况,因为我还可能收到我不关心的其他 Address 元素(也具有“Field”属性)。

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

蒂亚! 肖恩


仅使用 XML 模式无法完成所需的验证。

根据“XML 模式第 1 部分:结构”规范 http://www.w3.org/TR/xmlschema-1/#Model_Group_details ...

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

这并不是说您无法构建可以验证正确文档的模式。这意味着,您无法构建无法验证某些不正确文档的模式。当我说“不正确”时,我指的是违反您用英语规定的限制的文件。

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

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

根据您的架构,该文档是一个有效的地址。可以添加一个xs:独特的 http://msdn.microsoft.com/en-us/library/ms256146.aspx对您的架构进行约束,以便它拒绝此类损坏的文档。但即使使用 xs:unique,针对这样的模式进行验证也会声明其他一些不正确的文档是有效的 - 例如包含三个的文档<Address>元素,每个元素都有独特的Field属性,但没有一个具有Field="Zip".

事实上,不可能生成一个 W3C XML 模式来正式编码您所声明的约束。这<xs:all> http://msdn.microsoft.com/en-us/library/ms256182.aspx元素almost可以让你做到这一点,但它仅适用于元素,不适用于属性。而且,它不能与扩展一起使用,因此在 W3C XML Schema 中,您不能说“所有这些元素以任何顺序排列,加上任何其他元素”。


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

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

对于第一个选项,我认为你可以使用 Relax NG 来做到这一点。其缺点是,它不是一个标准,据我所知,它既没有得到广泛支持,也没有得到广泛发展。这就像学习盖尔语是为了表达思想一样。盖尔语没有什么问题,但它有点像语言的死胡同,而且我认为RelaxNG也是如此 https://stackoverflow.com/questions/2113137/is-there-a-relaxer-for-net-is-relaxer-alive-is-relaxng-viable.

对于第二个选项,一种方法是第一步验证您的架构,然后第二步:

A. 应用 XSL 转换来转换<Address>元素转换为以其 Field 属性值命名的元素。该转换的输出如下所示:

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

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

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

您需要扩展该架构来处理其他元素,例如<SomeOtherCrazyValue>在变换的输出中。或者,您可以构造 xsl 转换,以不发出不属于 {State,Street,Zip} 之一的元素。

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


EDIT- 实际上,Sean,再考虑一下,您可以使用步骤 B。假设您的 XSL 转换只是Removes仅来自文档<Address>Field 属性值不包含 State、Street 或 Zip 的元素。换句话说,就不会有<Address Field="SomeOtherCrazyValue"...>。该转换的结果可以使用 maxOccurs="3"、minOccurs="3" 和 xs:unique 通过您的架构进行验证。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

XML 架构:我可以使某些属性的值成为必需的,但仍允许使用其他值吗? 的相关文章

随机推荐

  • 我可以从 Jupyter Notebook 使用 Dataflow for Python SDK 吗?

    我想玩Python SDK 的数据流 https github com GoogleCloudPlatform DataflowPythonSDK来自 Jupyter 笔记本 我不确定需要什么依赖项 以及是否可以将代码分布在多个笔记本单元上
  • 在 python 中将输出捕获为 tty

    我有一个需要 tty 如 stdin 和 stderr 的可执行文件 并且希望能够测试它 我想输入 stdin 并捕获 stdout 和 stderr 的输出 这是一个示例脚本 test py import sys print stdin
  • 为什么我们在实体框架中使用并发检查属性

    我是实体框架的新手 任何人都可以通过示例解释为什么我们在实体框架中使用并发检查属性 在场景中我们使用此属性 提前致谢 这是当多个用户同时更新实体时处理数据库更改冲突的一种方法 添加ConcurrencyCheck属性意味着你正在告诉 实体框
  • LINQ to Entities 无法识别“System.String ToString()”方法,并且该方法无法转换为存储表达式

    我正在将一些内容从一台 mysql 服务器迁移到一台 sql 服务器 但我不知道如何使这段代码工作 using var context new Context foreach var item in collection IQueryabl
  • PHP 资产管道/框架

    背景 我正在致力于 现代化 一个现有的 PHP 驱动的网站 该网站最初是一个带有一些 php 方法的静态网站 它现在有一个移动网络应用程序 多个模型和大量动态内容 然而 随着时间的推移 应用程序本身的结构与它主要是静态站点时相比并没有太大变
  • ORACLE SQL 中的 MAX()

    我有一个表 存储已完成的维护任务的记录列表以及完成的日期和时间 我正在尝试执行子查询来提取具有最新日期的每个任务的记录 我的SQL语句是 SELECT ENGINEERING COMPLIANCE EO AS EO ENGINEERING
  • 多模块的 jacoco 配置不起作用

    我的 jacoco 配置发生了一些奇怪的事情 我无法弄清楚 我访问了堆栈溢出和其他平台上的多个线程并尝试了很多方法 但没有解决这个问题 我已经为多个模块设置了java代码覆盖率 这是我的项目结构 ABC module1 DEF module
  • 如何在 Objective-C 的动画中使视图振动? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有一个名为 qShake 的 UIView 当用户犯错误时 我希望该视图在一个小空间内短时间内从左到右晃动 我将如何创建动画来做到这一点
  • Delphi (Indy) TIdTCPClient 在线程中

    在互联网上 我看到通常将 TIdTCPClient 放置在自定义 TThread 后代中 为什么要这样做 有时我也在这样的线程中看到服务器 为什么 干杯 阿德里安 Indy 使用阻塞 I O 最好在线程中处理 这是 Indy 整体设计的核心
  • Java:以管理员身份运行

    Java 有没有办法要求系统控制管理员功能 当然不做 右键单击exe gt 以管理员身份运行 我想要的是 UAC 提供一个像 Windows Vista 或 Windows 7 中的框架 或者我在从 jar 生成 exe 时需要做一些设置吗
  • 从函数返回值时使用 std::move() 以避免复制

    考虑支持默认移动语义的类型 T 还要考虑下面的函数 T f T t return t T o f 在旧的 C 03 中 一些非最佳编译器可能会调用复制构造函数两次 一次用于 返回对象 一次用于o 在 c 11 中 由于t inside f
  • 具有多输入的多输出 GP?

    我正在尝试在 GPFlow 中使用多维输入数据实现多输出 GP 我已经看到从这个问题 https github com GPflow GPflow issues 709在 GPflow 中 通过 定义多维基本内核 然后在其上应用共区域 可以
  • 在 R 中,如何让 PRNG 在平台之间给出相同的浮点数?

    在 R 4 1 1 中运行以下代码会在平台之间产生不同的结果 set seed 1 x lt rnorm 3 3 print x 22 0 83562861241004716 intel windows 0 8356286124100471
  • Windows Phone - 运行时的 Storyboard TargetName

    如何在运行时为 DoubleAnimationUsingKeyFrames 设置 TargetName
  • Microk8s 节点未准备好 - InvalidDiskCapacity

    microk8s的节点不想启动 Kube system Pod 处于挂起状态 kubectl describe nodes说是警告InvalidDiskCapacity 我的服务器有足够的资源 PODS NAMESPACE NAME REA
  • Android Volley 对于一个请求返回两次结果

    我两天来一直在试图解决这个问题 但我完全被难住了 由于某种原因 我向队列发送一个请求 但 volley 返回两次 这会调用侦听器两次并使列表视图中的结果加倍 我打开了 Volley 的日志记录 可以看到请求被添加到队列中并返回 然后几秒钟后
  • 更改单选按钮上输入字段中的值

    我正在开发一个项目 用户必须在两个选项中选择一个 选项是单选按钮 目前我正在获取 keyup 事件的结果 当用户选择一个选项 然后在输入字段中输入值时 他会在另一个结果输入字段中得到结果 它工作正常 但是当用户想要更改选项并选择其他选项时出
  • 如何使用“ADDMORE”按钮在 Angular 6 中上传多个文件?

    你好 埃弗龙 我一直在尝试上传上面 图片 用例 我知道当我们只有一个文件时这很容易 但现在的情况不同了 它由带有文件的对象数组组成 现在我的问题是如何使用对象数组渲染 formdata 对象 其中每个对象都包含一个文件 对于动态形式 我使用
  • 无法通过新的 Android 资源目录在 Android Studio 中创建布局文件夹(错误:输入或选择限定符)

    Step 1 右键单击res文件夹 选择New gt Android资源目录 Step 2 选择layout在资源类型中 然后单击OK Result 名称错误 输入或选择限定符 菜单类型不会发生这种情况 我错过了什么吗 我必须创建目录 这是
  • XML 架构:我可以使某些属性的值成为必需的,但仍允许使用其他值吗?

    注意 我无法更改收到的 XML 的结构 我只能更改验证它的方式 假设我可以像这样获取 XML