【问题标题】:How to unmarshal an XML document using JAXB and a different, but compatible, context如何使用 JAXB 和不同但兼容的上下文解组 XML 文档
【发布时间】:2011-03-02 23:18:45
【问题描述】:

我正在尝试编写一个转换工具,它采用旧版 XML 文档(遵循 oldSchema.xsd)并将其转换为新的 XML 格式(遵循 newSchema.xsd)。

也许我完全错了,但第一步是创建一个中间模式,新旧 XML 文档都可以根据它进行验证。例如,假设我有一个 XML 文档

<Doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="old oldSchema.xsd" xmlns="old">

    <OldElement/>
</Doc>

我想把它转换成

<Doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="new newSchema.xsd" xmlns="new">

    <NewElement/>
</Doc>

oldSchema.xsd 将 Doc 定义为具有称为 OldElement 的必需元素的序列。 newSchema.xsd 将 Doc 定义为具有称为 NewElement 的必需元素的序列。我的中间模式有一个序列,可以选择 OldElement 或 NewElement。

显然,这里还有更多内容需要我以编程方式处理。在解组 OldElement XML 文件之前,我需要将命名空间“old”替换为我的中间命名空间,以便我可以使用通过我的中间上下文创建的 JAXB 实例。

这可能吗?我尝试实现我自己的XMLStreamReader,它将XMLInputFactory.newInstance().createXMLStreamReader() 委托给getNamespaceURI(*) 之外的所有方法。对于这些,我实现了诸如

之类的东西
public String getNamespaceURI() {
    String existingNS = delegate.getNamespaceURI();
    return subs.get(existingNS) == null ? existingNS : subs.get(existingNS)
}

在上面的示例中,subs 会将命名空间“旧”映射到命名空间“新”。我对 XMLStreamReader 中的所有 getNamespaceURI(*) 方法重复了此操作。然后我将NamespaceSubstitutionXMLReader 的一个实例传递给unmarshaller.unmarshal(XMLStreamReader)。未编组的对象树有一个正确类型的根节点,但它的所有子元素都是空的。我不太明白为什么这种方法不起作用,但话说回来,我对 Unmarshaller 的实现一点也不熟悉。

非常感谢任何帮助。

【问题讨论】:

    标签: xml replace namespaces jaxb


    【解决方案1】:

    我领导 EclipseLink JAXB (MOXy),但如果您只想转换 XML,我建议您使用 XSLT 和 javax.xml.transform API。

    【讨论】:

      猜你喜欢
      • 2011-07-25
      • 2016-05-29
      • 1970-01-01
      • 2011-01-29
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      相关资源
      最近更新 更多