java - 为什么我的 JAXB Unmarshaller 找不到在导入模式中声明的元素?

标签 java xsd xml-namespaces

我有两个具有循环依赖性的模式 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: Cannot find declaration of element 'foo'.

我已经通过(伪)设置了模式:

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

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

最佳答案

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

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> 时,并且该导入的 namespace 是它已经知道的 namespace ,然后它实际上忽略了它。因此在解析 B.xsd 时(在命名空间 http://foo.org/A 中),并且它找到了同一命名空间的导入,并忽略了它。

关于java - 为什么我的 JAXB Unmarshaller 找不到在导入模式中声明的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2252337/

相关文章:

java - 如果将 TreeMap 作为 Map 传递给它,Treemap 会使用吗

java - 用于检查前缀绑定(bind)到的命名空间的 XPath

java - 就地快速排序问题

xml - 错误 : It was detected that X is in namespace Y, 但此命名空间中的组件无法从架构文档中引用

java - 查询原始 XML 架构的 XSD 有效 XML

python - 生成使用默认命名空间的 XML

java - 开关有什么问题?

c++ - 如何从 XSD cxx 树对象写入 XML 文件?

java - 在 Java 8 中,使用 Woodstox 运行时 namespace 前缀会发生变化

c# - 将命名空间设置为 XElement