6

给定一个顶级 xsd 导入第二级,然后导入第三级,是否可以在第一级中使用第三级的类型?还是第一个必须直接导入第三个?

4

2 回答 2

3

好问题!从阅读规范,我真的不能说。它没有明确解决传递导入的问题。

在 Primer(第 0 部分)中,他们只讨论了一级导入:http ://www.w3.org/TR/xmlschema-0/#import

在结构(第 1 部分)中,它也只定义了直接导入http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#composition-schemaImport因为它谈到“一种解决此类外部组件”(我认为这意味着命名空间),也许可以合理地假设需要一种明确的方式来处理导入的模式 - 换句话说,每个导入模式都需要一个显式的命名空间。

谷歌搜索显示其他人也对这个问题感到困惑:

这些帖子最令人担忧的是不同的 xsd 处理器有不同的行为——这表明处理器的作者也很困惑。

尽管自那些帖子(2002 年、2005 年)以来这可能已经改变,但最明智的做法似乎是避免这个问题,而只使用直接导入,因为这适用于所有处理器。

正如我所说:好问题。


这是一个测试,用于检查 xsd 处理器(当然,这不能保证它适用于使用其他 xsd 处理器的其他人......)。我发现我最喜欢的一个(xmllint)不允许传递导入。

测试是三个模式:a.xsd导入b.xsd进而导入c.xsd;并且c.xsd中定义的类型是从a.xsd引用的:

<!-- a.xsd -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c="http://www.c.com" targetNamespace="http://www.a.com">
  <xsd:import namespace="http://www.b.com" schemaLocation="b.xsd"/>
<!--  UNCOMMENT FOR DIRECT IMPORT
  <xsd:import namespace="http://www.c.com" schemaLocation="c.xsd"/>
-->
  <xsd:element name="eg" type="c:TypeC"/>
</xsd:schema>

<!-- b.xsd -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:import namespace="http://www.c.com" schemaLocation="c.xsd"/>
</xsd:schema>

<!-- c.xsd -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.c.com">
  <xsd:simpleType name="TypeC">
      <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>
</xsd:schema>


<!-- a.xml -->
<eg xmlns="http://www.a.com">hello world</eg>

$ xmllint --schema a.xsd a.xml  --noout
a.xsd:6: element element: Schemas parser error : Element
'{http://www.w3.org/2001/XMLSchema}element', attribute 'type': References from
this schema to components in the namespace 'http://www.c.com' are not allowed,
since not indicated by an import statement.
WXS schema a.xsd failed to compile

错误消息是:References from this schema to components in the namespace 'http://www.c.com' are not allowed, since not indicated by an import statement.,表明 xmllint 的开发人员至少非常确定导入不是传递性的

于 2012-12-06T14:19:12.917 回答
1

如果type是你在说的话..<xs:Include>不是<xs:Import>..

答案是:Parser 负责将所有 XSD 链接在一起

请参见下面的示例:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <child>trial</child>
  <child2>trial2</child2>
  <trunk>
    <branch>1</branch>
    <branch>2</branch>
  </trunk>
  <specialchild>test</specialchild>
</root>

对于上面的 XML,我将设计一个 XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="include multiple XSDs2.xsd"/>
  <xs:element name="root" type ="root"/>
  <xs:complexType name="root">
    <xs:sequence>
      <xs:element name="child" type="xs:string" />
      <xs:element name="child2" type="xs:string" />
      <xs:element name="trunk" type="trunk"/>
      <xs:element name="specialchild" type="specialchild"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

其中类型trunk在import multiple XSDs2.xsd文件中定义并通过使用链接<xs:include>.. 链接(位于同一文件夹中).. 代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="include multiple XSDs3.xsd"/>
  <xs:complexType name="trunk">
    <xs:sequence>
      <xs:element maxOccurs="unbounded" name="branch" type="branch" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

并且类型分支是定义在include multiple XSDs3.xsd文件中定义的一个简单类型,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="branch">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="specialchild">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
</xs:schema>

*现在棘手的部分是:在定义的地方specialchild声明XSD_1XSD_3并且这两个 XSD 由 . 链接XSD_2。您可以观察到解析器默认情况下负责链接所有 XSD 并将它们全部视为一个!*

希望这能解决你的问题!

于 2012-12-06T05:40:49.500 回答