【问题标题】:JAXB Unable To Handle Attribute with Colon (:) in name?JAXB 无法处理名称中带有冒号 (:) 的属性?
【发布时间】:2011-03-01 16:28:30
【问题描述】:

我正在尝试使用 JAXB 来解组其架构由 DTD 定义的 XML 文件(啊!)。

DTD 的外部提供者已将元素属性之一指定为xml:lang

<!ATTLIST langSet
id ID #IMPLIED
xml:lang CDATA #REQUIRED
>

这进入了 xjc 生成的类(标准生成;没有 *.xjb 魔法):

@XmlAttribute(name = "xml:lang", required = true)
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
protected String xmlLang;

但是,当使用 JAXB 解组有效的 XML 文件时,xmlLang 属性始终为 null

当我编辑 XML 文件,将 xml:lang 替换为 lang 并将 @XmlAttribute 更改为匹配时,解组成功(即属性不是null)。

我确实找到了这个http://old.nabble.com/unmarshalling-ignores-element-attribute-%27xml%27-td22558466.html。但是,解决方案是转换为 XML Schema 等。我强烈倾向于直接从未更改的 DTD(因为它是外部提供并由 ISO 标准定义)。

这是一个 JAXB 错误吗?我是否在属性名称中遗漏了一些关于“命名空间”的内容?

FWIW, java -version = "build 1.6.0_20-b02" and xjc -version = "xjc version "JAXB 2.1.10 in JDK 6""

【问题讨论】:

  • 这是哪个 DTD? xml:lang 是一个 XML Schema 元属性,因此 DTD 描述的是源自 Schema 的东西,这向我暗示那里有一个完整的模式。
  • AFAIK,发布者仅提供 DTD。很难想象他们发布了基于模式的 DTD,但不提供后者。但是,我有一些相关工具的作者问我是否使用 Schema 来生成 JAXB 对象,所以那里可能有一些东西......
  • 感谢您的 nabble 链接。你让我的生活更轻松。

标签: attributes jaxb dtd unmarshalling


【解决方案1】:

通过在 JAXB 生成的类中将 xml: 替换为 namespace 声明来解决问题:

@XmlAttribute(name = "lang", namespace="http://www.w3.org/XML/1998/namespace", required = true)

在某种程度上,这是有道理的。

如果没有这种指导,JAXB 怎么知道如何解释原本未定义的命名空间xml:?当然,除非它像在http://java.sun.com/javase/6/docs/api/javax/xml/stream/XMLStreamReader.html#getNamespaceURI%28java.lang.String%29 中那样对xml: 实施了一些特殊情况的内部处理(参见第一个注意:

无论是 xjc 生成带注释的对象中的错误还是 unmarhaller 中的错误,或者只是需要在 xjc 进程中的某个位置进行映射,在我看来仍然是一个悬而未决的问题。

目前,它正在工作,它只需要一点 xjc 魔法,所以我相当高兴。

【讨论】:

  • 太棒了,我花了几个小时的研究! :D
【解决方案2】:

免责声明:虽然晚了 8 年,但我正在为迷失的灵魂添加这个答案,比如我自己试图理解从 DTD 自动生成 java 文件。

您可以通过 @XmlSchema 选项直接在 project-info.java 文件中为解组器设置项目范围的命名空间。

当从模式生成类时,这个文件应该由 xjc 自动生成,但是看起来 从 DTD 生成时,xjc 不会自动生成 package-info.java 文件!

但是,您可以手动制作此文件,并将其添加到与 xjc 生成的文件相同的包中。

文件如下所示:

package-info.java :

@XmlSchema(
    elementFormDefault=XmlNsForm.QUALIFIED, 
    xmlns = {
            @XmlNs(prefix="xlink", namespaceURI="http://www.w3c.org/1999/xlink"),
            @XmlNs(prefix="namespace2", namespaceURI="http://www.w3c.org/1999/namespace2")
    }) 

package your.generated.package.hierarchy;
import javax.xml.bind.annotation.*;

您可以根据需要添加任意数量的命名空间,只需在表单中添加一个新行:

@XmlNs(prefix="namespace", namespaceURI="http://www.uri.to.namespace.com")

与编辑生成的@XmlAttribute 相比,这样做的好处是不需要更改每个生成的 XmlAttribute,也不需要手动从 XmlAttribute 名称变量中删除命名空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2016-10-24
    • 2011-09-11
    相关资源
    最近更新 更多