我在我的项目中使用JAXB,但我不时遇到一些我无法解决的问题。我已经设置了这样的环境:
护甲等级
package com.fortresswars.entity.component;
@XmlType(name = "armor", namespace = "http://fortresswars.com")
public class ArmorComponent extends AbstractComponent
package-info.java
@XmlSchema(xmlns = @XmlNs(namespaceURI = "http://fortresswars.com", prefix = "fw"), elementFormDefault = XmlNsForm.UNQUALIFIED, namespace = "http://fortresswars.com")
package com.fortresswars.entity.component;
生成的架构标题几乎是正确的:
<xs:schema elementFormDefault="unqualified" version="1.0" targetNamespace="http://fortresswars.com" xmlns:fw="http://fortresswars.com" xmlns:tns="http://fortresswars.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
我唯一不喜欢的是JAXB放在那里的TNS前缀,我无法删除。我正在使用一个蚂蚁任务(com.sun.tools.jxc.SchemaGenTask
),我记得在某个地方读过这个问题。
生成的方案的其余部分如下。我只会展示有关盔甲的相关部分:
<xs:complexType name="armor">
<xs:complexContent>
<xs:extension base="tns:abstractComponent">
<xs:sequence>
<xs:element name="value" type="xs:short" minOccurs="0"/>
<xs:element name="type" type="tns:armor-type" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
使用护甲组件的元素:
<xs:complexType name="character">
<xs:complexContent>
<xs:extension base="tns:thing">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="armor" type="tns:armor"/>
<xs:element name="model" type="tns:model"/>
<xs:element name="status" type="tns:status"/>
<xs:element name="costs" type="tns:costs"/>
</xs:choice>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
为了对此进行测试,我创建了一个XML文档(请参阅TNS前缀,我需要将其添加,或fw
前缀,以及xmlns:fw)。
<?xml version="1.0" encoding="UTF-8"?><tns:character xmlns:tns="http://fortresswars.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="/home/shirkit/jMonkeyProjects/Fortress Wars/Core/schema/full.xsd">
<armor>
<value>5</value>
<type>NORMAL</type>
</armor>
</tns:character>
但是当我解组这个文档时,我得到的错误是:
Exception: unexpected element (uri:"", local:"armor"). Expected elements are <{http://fortresswars.com}armor>,<{http://fortresswars.com}attacks>,<{http://fortresswars.com}costs>,<{http://fortresswars.com}model>,<{http://fortresswars.com}abilities>,<{http://fortresswars.com}status>,<{http://fortresswars.com}movement>
我已将elementFormDefault设置为UNQUALIFIED,即使这不起作用。为什么我得到这个例外?我可以从生成的架构中删除TNS前缀吗?
答案 0 :(得分:1)
为http://fortresswars.com元素定义名称空间前缀时,需要为所有元素添加前缀,而不仅仅是character
。所以这应该有用
<?xml version="1.0" encoding="UTF-8"?>
<tns:character
xmlns:tns="http://fortresswars.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="/home/shirkit/jMonkeyProjects/Fortress Wars/Core/schema/full.xsd">
<tns:armor>
<tns:value>5</tns:value>
<tns:type>NORMAL</tns:type>
</tns:armor>
</tns:character>
架构中使用的tns
前缀与您用作解组的XML文本前缀的内容无关。您可以在xmlns:whatyoulike="http://fortresswars.com"
中选择任何其他人。将XML文档中的元素连接到模式文件中的定义的关键是命名空间URI,在您的情况下为“http://fortresswars.com”。如果将命名空间定义为默认命名空间,则可以省略每个元素的前缀:
<?xml version="1.0" encoding="UTF-8"?>
<character
xmlns="http://fortresswars.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="/home/shirkit/jMonkeyProjects/Fortress Wars/Core/schema/full.xsd">
<armor>
<value>5</value>
<type>NORMAL</type>
</armor>
</character>
如果您不想将模式文件与定义具有相同名称的类型或元素的其他模式文件一起使用,则XSD文件中的名称空间前缀有助于避免名称冲突。它不会强制您在要解组的xml文件中使用它。
另一方面,当你将对象变为XML时,文件package-info.java
定义了JAXB使用的前缀,但这仅适用于最新版本的JAXB,并且要确保正确的版本在在代码运行时使用。但您可以使用NamespacePrefixMapper
来控制它。