1

我在我的项目中使用 JAXB,但有时我会遇到一些我无法解决的问题。我已经像这样设置了我的环境:

装甲等级

package com.fortresswars.entity.component;

@XmlType(name = "armor", namespace = "http://fortresswars.com")
public class ArmorComponent extends AbstractComponent

包信息.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>

以及使用 Armor 组件的元素:

  <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 前缀吗?

4

1 回答 1

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,并且在您的代码运行时确保使用正确的版本并不总是那么容易。但是您可以使用 aNamespacePrefixMapper来控制它。

于 2012-07-25T20:31:38.453 回答