一个 xml 命名空间等于一个且只有一个模式文件? [英] One xml namespace equals one and only one schema file?

查看:22
本文介绍了一个 xml 命名空间等于一个且只有一个模式文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

...或为什么这些文件在 Visual Studio 2010 中验证,而在 xmllint1 中却没有验证?

...or Why do these files validate in Visual Studio 2010 but not with xmllint1?

我目前正在处理已发布的 xml 架构,其中原作者的习惯是将架构分解为多个 .xsd 文件,但其中一些架构文件具有相同的 targetNamespace.这真的允许"吗?

I'm currently working against a published xml schema where the original author's habit is to break down the schemas into several .xsd-files, but where some schema files have the same targetNamespace. Is this really "allowed"?

示例(极其简化):

File    targetNamespace    Contents
------------------------------------------------------------
b1.xsd  uri:tempuri.org:b  complex type "fooType"
b2.xsd  uri:tempuri.org:b  simple type "barType"

a.xsd   uri:tempuri.org:a  imports b1.xsd and b2.xsd
                           definition of root element "foo", that
                           extends "b:fooType" with an attribute
                           of "b:barType"

(下面是完整的文件内容.)

然后我有一个xml文件,data.xml,内容如下:

Then I have an xml file, data.xml, with this content:

<?xml version="1.0"?>
<foo bar="1" xmlns="uri:tempuri.org:a" xmlns:xs="http://www.w3.org/2001/XMLSchema" />

长期以来,我一直相信所有这些都是正确的,因为 Visual Studio 显然允许这种模式样式.但是,今天我决定设置一个命令行实用程序来验证 xml 文件,我选择了 xmllint.

For a long time, I have believed that all of this was correct, since Visual Studio apparently allows this schema style. However, today I decided to set up a command line utility for validating xml files, and I chose xmllint.

当我运行 xmllint --schema a.xsd data.xml 时,我收到了以下警告:

When I ran xmllint --schema a.xsd data.xml, I was presented with this warning:

a.xsd:4:元素导入:模式解析器警告:元素'{http://www.w3.org/2001/XMLSchema}导入':为命名空间uri:tempuri.org:b"跳过位于b2.xsd"的模式导入,因为这命名空间已使用位于b1.xsd"的架构导入.

a.xsd:4: element import: Schemas parser warning : Element '{http://www.w3.org/2001/XMLSchema}import': Skipping import of schema located at 'b2.xsd' for the namespace 'uri:tempuri.org:b', since this namespace was already imported with the schema located at 'b1.xsd'.

b2.xsd 的导入被跳过显然会导致这个错误:

The fact that the import of b2.xsd was skipped obviously leads to this error:

a.xsd:9:元素属性:模式解析器错误:属性 decl.酒吧",属性类型":QName 值{uri:tempuri.org:b}barType"无法解析为 (n) 简单类型定义.

a.xsd:9: element attribute: Schemas parser error : attribute decl. 'bar', attribute 'type': The QName value '{uri:tempuri.org:b}barType' does not resolve to a(n) simple type definition.

如果 xmllint 正确,我正在处理的已发布规范中会有错误.有吗? Visual Studio 会出错.是吗?

If xmllint is correct, there would be an error in the published specs I'm working against. Is there? And Visual Studio would be wrong. Is it?

我确实意识到 xs:importxs:include 之间的区别.现在,我只是不明白 xs:include 是如何解决问题的,因为:

I do realize the difference between xs:import and xs:include. Right now, I just don't see how xs:include could fix things, since:

  • b1.xsdb2.xsd 具有相同的 targetNamespace
  • 它们的 targetNamespacea.xsd
  • 不同
  • 他们并不(不需要)彼此了解
  • b1.xsd and b2.xsd have the same targetNamespace
  • they both differ in targetNamespace from a.xsd
  • and they do not (need to) know about each other

这是原始模式规范中的缺陷吗?我开始认为第三点至关重要.他们不知道彼此的事实是否应该导致一开始就把他们放在不同的命名空间中?

Is this a flaw in the original schema specification? I'm beginning to think that the third bullet point is crucial. Should the fact that they don't know about each other have led to placing them in different namespaces to begin with?

b1.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:b" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="fooType" />
</xs:schema>

b2.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:b" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="barType">
    <xs:restriction base="xs:integer" />
  </xs:simpleType>
</xs:schema>

a.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="uri:tempuri.org:a" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:b="uri:tempuri.org:b">
  <xs:import namespace="uri:tempuri.org:b" schemaLocation="b1.xsd" />
  <xs:import namespace="uri:tempuri.org:b" schemaLocation="b2.xsd" />
  <xs:element name="foo">
    <xs:complexType>
      <xs:complexContent>
        <xs:extension base="b:fooType">
          <xs:attribute name="bar" type="b:barType" />
        </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

<小时>

注意事项:

1) 我使用的是 libxml2/xmllint 的 Windows 端口,位于 www.zlatkovic.com.

1) I'm using the Windows port of libxml2/xmllint found at www.zlatkovic.com.

推荐答案

这里问题的关键是当你有两个不同的 <import> 元素时,当它们同时引用同一个命名空间.

The crux of the problem here is what does it mean when you have two different <import> elements, when both of them refer to the same namespace.

当您考虑到 <import>schemaLocation 属性是完全可选的时,这有助于澄清含义.当您忽略它时,您只是在说我想将命名空间 XYZ 的模式导入 this 模式".schemaLocation 只是提示在哪里可以找到其他模式的定义.

It helps to clarify the meaning when you consider that the schemaLocation attribute of <import> is entirely optional. When you leave it out, you're just saying "I want to import schema of namespace XYZ into this schema". The schemaLocation is just a hint as to where to find the definition of that other schema.

<import> 的确切含义在您阅读 W3C 规范时有点模糊,可能是故意的.因此,解释各不相同.

The precise meaning of <import> is a bit fuzzy when you read the W3C spec, possibly deliberately so. As a result, interpretations vary.

一些 XML 处理器允许同一命名空间使用多个 <import>,并且基本上将所有 schemaLocation 合并到一个目标中.

Some XML processors tolerate multiple <import> for the same namespace, and essentially amalgamate all of the schemaLocation into a single target.

其他处理器更严格,并决定每个目标命名空间只有一个 <import> 有效.当您认为 schemaLocation 是可选的时,我认为这是更正确的.

Other processors are stricter, and decide that only one <import> per target namespace is valid. I think this is more correct, when you consider that schemaLocation is optional.

除了您提供的 VS 和 xmllint 示例之外,Xerces-J 也是超严格的,并且对于相同的目标命名空间会忽略后续的 <import>,给出与 xmllint 大致相同的错误做.另一方面,XML Spy 更加宽松(但是,XML Spy 的验证是出了名的不稳定)

In addition to the VS and xmllint examples you gave, Xerces-J is also super-strict, and ignores subsequent <import> for the same target namespace, giving much the same error as xmllint does. XML Spy, on the other hand, is much more permissive (but then, XML Spy's validation is notoriously flaky)

为了安全起见,您应该拥有这些多重导入.一个给定的命名空间应该有一个单一的主"文档,而每个子文档又都有一个<include>.这个主人通常是高度人工的,只充当容器.对于这些子文档.

To be safe, you should not have these multiple imports. A given namespace should have a single "master" document, which in turn has an <include> for each sub-document. This master is often highly artificial, acting only as a container. for these sub-documents.

据我所见,这通常包括 XML Schema 在最大工具兼容性方面的最佳实践",但有些人会认为这是一种破坏优雅模式设计的技巧.

From what I've seen, this generally consists of "best practise" for XML Schema when it comes to maximum tool compatibility, but some will argue that it's a hack that takes away from elegant schema design.

嗯.

这篇关于一个 xml 命名空间等于一个且只有一个模式文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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