【问题标题】:How to find out XSD file dependencies如何找出 XSD 文件的依赖关系
【发布时间】:2018-03-28 21:55:09
【问题描述】:

我想存储解析特定 XSD 文件所需的所有 XSD 文件。 This answer 表示我们应该寻找 xs:includexs:import 属性。

但是元素内部使用的命名空间呢?通常根元素(模式声明)有多个命名空间声明。 如果我们在 XSD 文件中遇到这些,我们不应该也包含这些命名空间的 XSD 吗?

例如,在这个 XSD 文件中,我们是否不需要包含定义 urn:oma:xml:xdm:extensionsurn:ietf:params:xml:ns:resource-listshttp://www.w3.org/2001/XMLSchema 命名空间的 XSD?

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
    targetNamespace="urn:3gpp:ns:mcpttGroupInfo:1.0"
    xmlns:mcpttgi="urn:3gpp:ns:mcpttGroupInfo:1.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:oxe="urn:oma:xml:xdm:extensions"
    xmlns:rl="urn:ietf:params:xml:ns:resource-lists"
    elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xs:import namespace="urn:oma:xml:xdm:extensions"/>
    <xs:import namespace="urn:ietf:params:xml:ns:resource-lists"/>

    <!-- XSD element and type definitions -->

</xs:schema>

【问题讨论】:

    标签: xml xsd schema


    【解决方案1】:
    http://www.w3.org/2001/XMLSchema
    

    是一个用于定义模式元素的特殊命名空间,它可以自动理解并且按照惯例(尽管不是必需的)使用“xs”别名。

    你的线路

    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    

    只为架构元素定义默认的命名空间别名。

    要包含 urn:oma:xml:xdm:extensionsurn:ietf:params:xml:ns:resource-lists 的架构,您需要提供 schemaLocation 属性,例如

    <xs:import namespace="urn:oma:xml:xdm:extensions" 
               schemaLocation="http://yourSchemaLocation/yourSchema.xsd"/>
    

    注意schemaLocation 可以是相对的,根据我对您自己的模式的经验,这可能更合适,当然也更方便。所以也许

    <xs:import namespace="urn:oma:xml:xdm:extensions" 
               schemaLocation="./yourSupportingSchemaLocation/yourSchema.xsd"/>
    

    会是一个更好的例子。

    【讨论】:

    • 在导入和包含的情况下,我们必须显式提供模式位置是很痛苦的。使schemaLocation 相对使事情更便携。我想知道为什么这是强制性的,而不是模式声明的位置属性。此外,I read here,架构的显式位置被认为是一种不好的做法。文章说“通常文档消费者应该选择模式,而不是文档生产者。”
    【解决方案2】:

    如果我们在 XSD 文件中遇到这些,我们不应该将这些命名空间的 XSD 也包括在内吗?

    如果我们在 XSD 架构文档中遇到命名空间 N 的命名空间声明,则将出现以下情况之一:

    1. 它是 XSD 命名空间和在架构中的元素上声明的前缀。
    2. 它是当前架构文档的目标命名空间,声明的前缀用于对目标命名空间中的类型、元素、属性等的引用。
    3. 它不是目标命名空间,用于对元素、类型、属性等的引用。
    4. 它不用于元素、类型、属性等的引用(模式声明),但它是模式文档本身中使用的某些元素或属性的命名空间(例如,在 xsd:annotation 元素中,或作为 XSD 元素上的外部命名空间属性)。
    5. 架构文档中根本没有使用它。

    如果我们正在寻求收集一组足以验证当前架构文档中定义的元素、属性和类型的架构文档(或者,或多或少等效地,直接或间接、显式引用的架构文档集或隐含地,从当前模式文档中),那么:

    1. 案例 1 无关紧要:XSD 命名空间的架构内置于每个符合要求的 XSD 验证器中,无需收集。
    2. 案例 2 要求我们收集当前正在阅读的架构文档。 (大概我们已经知道了,否则我们为什么要首先阅读它?)
    3. 在情况 3 中,要么有一个用于命名空间的 xsd:import,在这种情况下,当我们处理 xsd:import 元素时会处理它,或者没有这样的导入,在这种情况下是当前架构文档不符合标准,当符合标准的模式处理器尝试从中构造模式时会引发错误。
    4. 在情况 4 中,命名空间用于当前模式文档中(例如,在包含在 xsd:documentation 元素中的 HTML 段落中);如果我们想验证当前模式文档中的相关元素或属性,我们将需要该命名空间的模式文档。但是没有迹象表明所讨论的名称空间可以或将用于要针对此模式进行验证的文档中。可以在这些文档中使用它的唯一有用指示是 xsd:import 元素。
    5. 在第 5 种情况下,命名空间声明很粗鲁,没有明显的用途。 (它可能是组织中使用的架构文档模板的一部分,因为所讨论的名称空间经常在组织的架构文档中使用——我的架构文档通常为 XHTML 命名空间声明一个前缀——但在这个特定的架构文档中没有使用无论出于何种原因。)无需收集此命名空间的架构文档。

    在您提供的示例文档中,有四个命名空间声明。一种属于情况1:

    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    

    一个属于情况2:

    xmlns:mcpttgi="urn:3gpp:ns:mcpttGroupInfo:1.0"
    

    两个属于案例 3(或可能是案例 5),对于这些还有 xsd:import 指令:

    xmlns:oxe="urn:oma:xml:xdm:extensions"
    xmlns:rl="urn:ietf:params:xml:ns:resource-lists"
    

    如果我们通过命名空间声明而不是 xsd:import 和 xsd:include 指令来驱动我们的集合策略,那么这里的区别将是我们 (a) 将 XSD 架构文档的架构添加到我们的集合中,并且 (b) 可能搜索对于当前模式文档的目标命名空间的其他可用模式文档。 (在某些情况下,这可能是可取的;在其他情况下,我们对同一个命名空间有不同的模式,并且收集所有模式会适得其反,因为它会产生一组冗余且可能自相矛盾的声明。)

    【讨论】:

    • 感谢这个全面的答案,不幸的是,由于我对 XML 的了解有限,我很难理解它,所以我创建了a little project on GitHub 来练习你提到的各种选项。现在我可以从您的回答中受益更多。来自Beginning XML 5th Edition 的章节也被证明非常有用。我发布了自己的答案以详细说明。
    【解决方案3】:

    总而言之,在定义 XML 模式时,包含标签必须具有位置属性。否则架构将无效。 尽管 import 和 include 语句使用的 XSD 文件可能会丢失,这可能会触发验证器进行宽松的验证,但它们应该被视为依赖项 因为打算在 XSD 架构中使用它们。

    由于 XSD 模式也是实例文档,因此它们也依赖于其模式文档。但是对于这种特殊情况,它们位于“http://www.w3.org/2001/XMLSchema”(XML 模式命名空间)命名空间中,该命名空间被硬编码到 XML Validator 中。所以不需要提供。

    对于从自定义模式创建的“其他”实例文档(这不是我的问题的一部分,仅提及完整性),模式位置不是强制性的,尽管可以明确定义。如果未定义,则可以指示 XML 验证器以编程方式使用某些模式 - 最后选择哪个文件取决于实现。

    但它肯定必须找到一些模式来验证实例文档 - 如果有一个命名空间声明开始。 如果此架构有一些包含和导入,则这些文件也必须可用,并且它们必须位于 location 属性中指定的位置。

    【讨论】:

    • 您说“在定义 XML 模式时,...导入标签必须具有位置属性”——并非如此。 xsd:import 元素可能具有 schemaLocation 属性,但不是必需的。处理器可能有其他方法为导入的命名空间查找模式。
    • 对,我编辑了这个。我在没有schemaLocation 的情况下尝试了import,并且我使用的验证器引发了错误。但从技术上讲,XSD 是有效的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    相关资源
    最近更新 更多