gpt4 book ai didi

xml - XML模式头和命名空间配置

转载 作者:行者123 更新时间:2023-12-03 13:39:10 25 4
gpt4 key购买 nike

从DTD迁移到XSD,由于某种原因,过渡是坎bump的。我了解一旦进入<xs:schema>根标记后如何定义架构,但是事实证明,越过标题和名称空间声明的内容对我来说尤其令人困惑。

我一直在尝试按照W3S精心安排的教程,但即使该教程似乎也需要很多知识。

我想我正在寻找的是国王的英文解释,其中哪些属性起作用,它们在哪里以及为什么:


xmlns
xmlns:xs
xmlns:xsi
targetNamespace
xsi:schemaLocation


在某些情况下,我看到这些元素/属性的不同变体,例如xsi似乎有两个不同的符号,例如xsi:schemaLocation="..."xs:import schemaLocation="..."

我想在所有这些细微变化之间,我似乎无法做出每一个的正面或反面。在此先感谢您为这种混乱带来任何清晰度!

最佳答案

您需要了解的第一件事是XML名称空间。如果您有时间浪费,可以阅读the specification。我发现这是与XML相关的更清晰的规范之一。如果您不理解其中所说的所有内容,这并不重要,这是一个很好的基础。但这是一个简短的总结。

XML元素和属性具有名称。当您看到<test att="hello"/>时,您将看到一个名为“ test”的元素,其中有一个名为“ att”的属性。但这并不是全部故事...

XML是一种语法,允许您混合来自不同标记语言的内容。例如,当使用XSLT将XML文档转换为XHTML页面时,您至少要处理XML中定义的三种标记语言:输入文档的XSLT和XHTML。如果每个人都保留自己的元素/属性名称,并且不允许发生冲突,那么这种混合将变得非常困难。

输入XML名称空间。 XML名称空间定义了一个“球形”,其中的元素和属性名称具有实际的语义。元素“模板”在XSLT名称空间中具有明确定义的含义。元素“ complexType”在XML Schema名称空间中具有定义明确的含义。如果您希望使用自己的XML标记语言来使用,则可以在其他名称空间中使用。

为了确保名称空间是唯一的,您需要提供一些唯一的标识符。该规范基于URI的使用,通常采用HTTP URL的形式。原因很简单:此类URL往往是良好的唯一标识符。但这也是造成混乱的一个非常普遍的原因,因为人们认为URL确实具有含义,或者将在XML处理期间通过网络进行访问。非常清楚,事实并非如此!不需要URL指向任何现有资源。它不会进行任何转换或解析为网络地址。即使两个URL指向完全相同的事物,但它们之间的差异只有一个字符,因此它们被视为不同的命名空间。名称空间标识符只是一个字符串,在此区分大小写。而已。

随着名称空间的引入,XML元素或属性的名称突然由两部分组成:名称空间和本地名称。 <test/>中的“测试”仅是本地名称。所谓的“完全限定名称”由名称空间和本地名称的某种不可见组合组成。有时使用符号{namespace URI}local-name,但这仅是约定。

因此,现在我们需要能够在XML文档中使用名称空间。为了声明名称空间,XML具有硬编码机制。它使用特殊字符串xmlns允许进行名称空间声明。可以通过以下两种方式之一完成此操作:将名称空间绑定到前缀,或将其声明为默认名称空间。

绑定到前缀时,格式如下:xmlns:prefix="namespace URI"。这是一个XML文档中的示例:

<foo:root xmlns:foo="http://www.foo.com">
<foo:test />
</foo:root>


现在,我们已将名称空间 http://www.foo.com绑定到前缀 foo。无论将此前缀放在元素或属性名称的前面,我们都声明它们是该命名空间的一部分。

这里要注意的重要一点是实际前缀绝对没有任何意义。以下XML文档在语义上完全相同:

<bar:root xmlns:bar="http://www.foo.com">
<bar:test />
</bar:root>


前缀只是表示名称空间的一种便捷方式。它使我们不必每次都完全使用URI。

接下来是默认名称空间。可以使用 xmlns="namespace URI"声明默认名称空间。您可以抽象地认为这是将名称空间绑定到空前缀。再次是相同的XML文档,但是这次没有前缀:

<root xmlns="http://www.foo.com">
<test />
</root>


使用起来比较方便。那么为什么根本没有前缀呢?当我们混合来自不同名称空间的内容时,它们开始发挥作用:

<root xmlns="http://www.foo.com">
<so:test xmlns:so="http://stackoverflow.com" />
</root>


这次是另一个XML文档。我们的 root元素位于 http://www.foo.com命名空间中,但是 test元素位于 http://stackoverflow.com中,因为我们已经绑定了 so前缀并在 test上使用了它。

您在这里还注意到,可以在XML文档中的任何元素上声明名称空间。然后,该声明的范围(并绑定到前缀(如果适用))将成为该元素及其内容。

有时这可能会造成混淆,甚至更是如此,因为声明可能会相互覆盖。检查此文件:

<root xmlns="http://www.foo.com">
<test />
<so:test xmlns:so="http://www.stackoverflow.com" xmlns="http://www.bar.com">
<test />
</so:test>
</root>


花一点时间弄清楚每个元素在哪个命名空间中。这是一个很好的练习。

root在命名空间 http://www.foo.com中。第一个 test元素也位于该名称空间中,因为我们没有使用前缀,但位于该默认名称空间的范围内。前缀为 test的第二个 so元素位于命名空间 http://www.stackoverflow.com中,因为这是我们将前缀绑定到的内容。

因此,这是第三个最里面的 test元素。它在哪个命名空间中?它没有前缀,因此必须在默认名称空间中。但是,我们在第二个测试元素中更改了默认名称空间!因此,现在最里面的元素属于 http://www.bar.com命名空间,而不是 http://www.foo.com

感到困惑了吗?只要记住以下几点:


名称空间只是一个字符串。 URI被用作具有唯一标识符的便捷方式。
前缀用于表示名称空间,但其名称毫无意义。只需将其视为占位符即可。
您可以设置默认名称空间。其范围内所有没有前缀的元素将成为其一部分。




ew现在,进入W3C XML Schema。所有这些与它有什么关系?

好吧,对于初学者来说,XML Schema本身是一种用XML定义的标记语言。因此,它有理由得到它自己的名称空间。该名称空间正式为 http://www.w3.org/2001/XMLSchema。如果将 S写为小写,那是错误的。开始了解为什么有些人真的讨厌名称空间吗?

以下三个文档完全相同:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</xsd:schema>

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

<schema xmlns="http://www.w3.org/2001/XMLSchema">
</schema>


重要的是我们正在使用XML Schema名称空间中的内容。但是,按照惯例,人们倾向于在XML模式中使用前缀 xsxsd

当我们有一个XML文档时,我们可能希望指定其模式所在的位置。一个XML文档可能涉及多个模式,因为如前所述,语言可以混合在XML中。为了说XML文档是模式的实例,再次有一个特殊的名称空间: http://www.w3.org/2001/XMLSchema-instance。按照惯例,我们倾向于将此名称空间绑定到前缀 xsi。但是,这不是强制性的。

在该架构实例名称空间中定义了几个属性。其中有 schemaLocationnoNamespaceSchemaLocation。看一下这个文件:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.foo.com/schema">
</root>


那里发生了什么?首先,我们声明要将前缀 xsi绑定到名称空间 http://www.w3.org/2001/XMLSchema-instance。然后,我们在该命名空间中使用了一个属性: noNamespaceSchemaLocation。该属性告诉我们模式的位置,以验证文档中那些不在任何特定名称空间中的部分。以下XML文档在语义上完全相同:

<root xmlns:huh="http://www.w3.org/2001/XMLSchema-instance" huh:noNamespaceSchemaLocation="http://www.test.com/schema">
</root>


请记住,前缀名称没有意义。他们是占位符。那么,那个 noNamespaceSchemaLocation属性是什么?基本上,它告诉我们可以在哪里找到模式。现在与名称空间URI相反,这绝对是可以用来从网络或本地存储中获取内容的东西。根据文档中声明的模式进行验证的XML处理器可能会尝试获取它。

然后有一个事实,它叫做 noNamespaceSchemaLocation。模式定义“目标名称空间”。这是要声明它定义的元素和属性属于哪个名称空间。但是可以省略目标名称空间。在这种情况下,我们有一个没有名称空间的XML文档架构。这样的模式可以用 noNamespaceSchemaLocation引用。

在许多情况下,架构实际上会定义一个名称空间。为了说出哪个模式属于哪个名称空间,我们可以使用 http://www.w3.org/2001/XMLSchema-instance名称空间中的另一个属性: schemaLocation。该属性可以包含名称空间URI和架构URI对(以空格分隔)。假设我们有一个位于 http://www.foo.com的名称空间 http://www.myschemas.com/foo-schema的架构。然后我们可以声明如下:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema">
</root>


这是具有多个名称空间-位置对的示例:

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.foo.com http://www.myschemas.com/foo-schema http://www.bar.com http://www.randomschemas.com/bar-schema">
</root>


您在这里需要记住的是, http://www.w3.org/2001/XMLSchema-instance内容用于作为模式实例的XML文档中。名称空间 http://www.w3.org/2001/XMLSchema是用于定义模式本身的名称空间。



因此,到现在为止,我们已经对URI和具有特殊含义的怪异属性不知所措。命名空间就是这样:它们看起来非常复杂,直到您弄清楚它们有多简单为止。只需密切注意将什么前缀绑定到什么名称空间URI,并知道URI定义了什么。

我需要为您的问题解决的架构还有两件事: xs:importxs:include。请注意,由于我们正在谈论W3C XML Schema,因此在这里如何使用 xs前缀约定。

include元素可用于组合具有相同目标名称空间的架构。基本上,它使我们可以将模式模块化为更小的部分,并将它们放在一起。

import元素的功能确实相同,但是对于具有不同目标名称空间的架构。这使我们可以为不同的标记语言组合架构。



因此,回顾一下:


xmlns:用于指定默认名称空间。
xmlns:prefix:用于将名称空间绑定到 prefix
http://www.w3.org/2001/XMLSchema:XML模式的名称空间。按照惯例,通常绑定到前缀 xs,但这不是强制性的,也不是自动完成的。
http://www.w3.org/2001/XMLSchema-instance:定义一堆东西的名称空间,可用于声明XML文档如何成为架构实例的详细信息。按照惯例,通常绑定到前缀 xsi,但这不是强制性的,也不是自动完成的。
targetNamespace:可以在XML架构(在根元素上)中使用的属性,用于指定这是哪个命名空间的架构定义。
schemaLocation:由名称空间 http://www.w3.org/2001/XMLSchema-instance定义的属性之一,用于指示在何处可以为一个或多个名称空间找到一个或多个模式。


我的最终建议是:找到一些方便的方法来根据模式验证文档并进行一些尝试。试用名称空间,包含和导入。使用多个名称空间制作文档,然后尝试进行范围界定。

之后,检查XML本身,XML名称空间和XML Schema的规范。这是一本铁杆的书,但是如果您逐步学习它,您将了解到,使用XML多年后,许多人似乎仍然会怀念。最终,一切都会变得有意义。

祝好运!

关于xml - XML模式头和命名空间配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8229740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com