【发布时间】:2013-02-13 03:41:46
【问题描述】:
我需要使用 XSOM 解析 XSD,但此 XSD 包含循环导入。
A.xsd
<xs:schema xmlns=”ns1” targetNamespace=”ns1”>
<xs:import namespace=”ns2” schemaLocation=”B.xsd”/>
<xs:element name=”MyElement” type=”xs:string”/>
</xs:schema>
B.xsd
<xs:schema xmlns=”ns2” targetNamespace=”ns2” xmlns:ns1=”ns1”>
<xs:import namespace=”ns1” schemaLocation=”A.xsd”/>
<xs:complexType name="MyComplex">
<xs:sequence>
<xs:element ref="ns1:MyElement" minOccurs="0"/>
<xs:sequence>
<xs:complexType>
</xs:schema>
XSOM 无法解析模式,因为它检测到由于循环导入而已经定义的元素。所以我试图通过外部化由 A 定义并在 B 中使用的元素来打破循环导入。
C.xsd 包含 B 使用的来自 A 的元素。注意这些元素在 A 中没有使用。不要问我为什么在 A 中定义了这些元素。
<xs:schema xmlns=”ns1” targetNamespace=”ns1”>
<xs:element name=”MyElement” type=”xs:string”/>
</xs:schema>
A.xsd 变成
<xs:schema xmlns=”ns1” targetNamespace=”ns1”>
<xs:import namespace=”ns2” schemaLocation=”B.xsd”/>
</xs:schema>
B.xsd(导入 C.xsd 而不是 A.xsd)变为
<xs:schema xmlns=”ns2” targetNamespace=”ns2” xmlns:ns1=”ns1”>
<xs:import namespace=”ns1” schemaLocation=”C.xsd”/>
<xs:complexType name="MyComplex">
<xs:sequence>
<xs:element ref="ns1:MyElement" minOccurs="0"/>
<xs:sequence>
<xs:complexType>
</xs:schema>
XSOM 可以解析 XSD。但现在我无法使用以下代码创建架构:
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
sf.setResourceResolver(new MyResourceResolver());
我使用与 JDK 1.7 捆绑在一起的标准实现。我得到了例外:
src-resolve: Cannot resolve the name 'ns1:MyElement' to a(n) 'element declaration' component.
问题是资源解析器是为 B 命名空间调用的,而不是为 A 命名空间调用的,这是有意义的。由于命名空间 A 由 A.xsd 和 C.xsd 共享,因此资源解析器无法找到 C.xsd 中定义的元素。
循环导入是否有效?是否可以中断循环导入,使其可以由XSOM 解析,然后由SchemaFactory 加载?
【问题讨论】: