【问题标题】:JAXB issue with missing namespace definition缺少命名空间定义的 JAXB 问题
【发布时间】:2014-08-29 02:21:22
【问题描述】:

所以我四处寻找解决这个特定问题的方法,我希望有人能给我指明一个好的方向。

我们以 XML 格式接收数据,并且我们只有 XSD 来验证数据。所以我使用 JAXB 来生成 Java 类。当我去解组一个示例 XML 时,我发现缺少一些属性值。事实证明,架构期望这些属性是 QName,但数据提供者没有在 XML 中定义前缀。

例如,一个 XML 属性值是 "repository:<uuid>",但命名空间前缀“repository”从未在数据集中定义。 (不要介意提供商的最佳实践建议对其进行定义!)

所以当我去解组一个样本集时,带有指定前缀的 QName 属性(我上面的样本中的“repository”)是 NULL!所以看起来 JAXB 正在“丢弃”那些具有未定义命名空间前缀的属性 QName 值。我很惊讶它甚至没有保留本地名称。

理想情况下,我希望保持原样,但看起来我无法在绑定时将 QName 映射到字符串(架构到 Java)。

我尝试“手动”将命名空间定义插入 XML,它就像一个魅力。最简单的方法是什么?

有没有办法在运行时“插入”命名空间映射/定义?还是在绑定时“全局”定义它?

【问题讨论】:

  • 我强烈建议您发布 CSD 和 XML 文档的相关部分。您收到的 XML 仍然很可能不符合 XSD,这将成为 JAXB 解组的问题。如果您已经确定 XML 实际上符合 XSD(例如,使用在线验证工具),请说出来(以便 SO 帮助者将其排除在外)。
  • 我想知道是否应该提供更多细节,但在我的平板电脑上有点困难。下次我将提供代码的实际出价。感谢您的反馈。

标签: java xml jaxb xsd xml-namespaces


【解决方案1】:

最简单的方法是使用字符串而不是 QName。可以使用javaType自定义to achieve this

如果你想在运行时添加前缀/命名空间映射,有很多方法可以做到:

  • 与上述类似,您可以提供自己的 QName 转换器,它会考虑您的前缀。
  • 您可以在两者之间放置一个 SAX 或 StAX 过滤器,并在 startDocument 中声明其他前缀。
  • 您真正需要的是将前缀映射添加到UnmarshallingContext.environmentNamespaceContext。我检查了源代码,但找不到直接简单的方法。

我个人会实现一个 SAX/StAX 过滤器来在事件级别“预处理”您的 XML。

【讨论】:

  • 我采纳了您的建议,它确实有效。我基本上实现了自己的 XMLStreamReader 并评估了特定字符串的响应。这稍微限制了灵活性,但我希望日期提供者最终会尽快解决这个特定问题。
猜你喜欢
  • 1970-01-01
  • 2011-09-11
  • 2015-02-01
  • 2014-06-07
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
相关资源
最近更新 更多