2

我有两个具有循环依赖关系的模式 A 和 B(这是一个中间步骤)。我用作输入的 XML 文件根据 xmllint 和 Visual Studio 对架构进行验证。Eclipse 告诉我这两个模式都包含两个同名的全局组件。

A.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
  targetNamespace="http://foo.org/A"
  xmlns="http://foo.org/A"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

<xs:import schemaLocation="b.xsd" />

B.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
  xmlns:foo="http://foo.org/A"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

  <xs:import namespace="http://foo.org/A" schemaLocation="a.xsd" />

我传递给 Unmarshaller 的 XSD 是 A.xsd。当它遇到 B.xsd 中定义的元素时,它会抱怨:

org.xml.sax.SAXParseException:cvc-elt.1:找不到元素“foo”的声明。

我通过(伪)设置了架构:

InputStream in = .. A.xsd
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
return factory.newSchema(new StreamSource(in);

谁能解释我做错了什么?谢谢。

4

1 回答 1

1

<xs:import>用于将其他模式中定义的命名空间导入当前模式。该schemaLocation属性只不过是关于在哪里可以找到其他命名空间的提示。

在 的情况下B.xsd,您是说要导入名称空间http://blah.org,并且该名称空间由A.xsd.

在 的情况下A.xsd,您的导入B.xsd并未指定您要导入的命名空间。

如果A.xsdB.xsd代表不同的命名空间,则import需要明确指定。

另一方面,如果您只是试图在同一命名空间中内联另一个模式文件中的元素,那么该include指令更合适。


编辑:好的,看到您的架构片段,我可以说这<xs:import>绝对不是正确的做法。两者A.xsdB.xsd都在同一个命名空间 ( http://foo.org/A) 中定义元素,因此您应该使用它<xs:include>

当 Java 遇到一个<xs:import>,并且该导入的名称空间是它已经知道的名称空间时,它实际上会忽略它。因此,当它正在解析B.xsd时(在命名空间中http://foo.org/A),它找到了同一个命名空间的导入,它忽略了它。

于 2010-02-12T14:27:18.717 回答