我正在尝试使用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
)。< / p>
我确实找到了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”和xjc -version
=“xjc版本”JDK 6中的JAXB 2.1.10“”
答案 0 :(得分:5)
通过在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
魔法,所以我很开心。
答案 1 :(得分:1)
免责声明:尽管晚了8年,但我还是为那些迷失的灵魂(例如我自己,试图从DTD理解自动生成Java文件)添加了此答案。
您可以通过@XmlSchema选项在project-info.java文件中直接为unmarshaller设置项目范围的命名空间。
从模式生成类时,此文件应由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名称变量中手动删除名称空间。