JAXB,xs:any和targetNamespace

时间:2010-09-27 17:03:58

标签: java xml xsd jaxb

我有一个定义以下架构的XSD:

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns="http://example.com/2010/aa/"
       xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
       xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
       xmlns:aa="http://example.com/2010/aa/"
       targetNamespace="http://example.com/2010/aa/"
       elementFormDefault="qualified">
...
<xs:element name="user" type="aa:User"/>
<xs:complexType name="User">
  <xs:sequence>
      <xs:element ref="aa:firstName" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="aa:lastName" minOccurs="0" maxOccurs="1"/>
      ...
      <xs:any namespace="##targetNamespace" processContents="skip" maxOccurs="unbounded" />
  </xs:sequence>
  <xs:anyAttribute processContents="skip" />
</xs:complexType>

<xs:element name="profile" type="aa:Profile"/>
<xs:complexType name="Profile">
 <xs:sequence>
    <xs:element ref="aa:username" minOccurs="0" maxOccurs="1"/>
    <xs:element ref="aa:accountStatus" minOccurs="0" maxOccurs="1" />
    <xs:element ref="aa:roleid" minOccurs="0" maxOccurs="1"/>
    ...
    <xs:element ref="aa:userid"/>
 </xs:sequence>
 <xs:anyAttribute processContents="skip" />
</xs:complexType>

当JAXB正在编组生成的对象时,它定义了以下内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user xmlns:ns2="http://example.com/2010/aa/">...</user>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<profile xmlns="http://example.com/2010/aa/">...</profile>

查看一个名称空间如何 xmlns:ns2 ,另一个是 xmlns 。这是因为用户的所有元素都符合aa命名空间的条件,但是由 xs:any 标记定义,因此需要定义两个命名空间。

配置文件没有xs:any标记,也不需要定义多个名称空间。这是我的解释,因为如果我从用户定义中删除xs:any,它将从生成的XML中删除 ns2

我如何告诉JAXB targetNamespace aa 是同一名称空间,因此它不包括两者?

2 个答案:

答案 0 :(得分:3)

您可以尝试使用NamespacePrefixMapper来覆盖首先生成前缀的方式:

NamespacePrefixMapper mapper = new NamespacePrefixMapper() {
    public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
        return "";
    }
};
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);

我在那里返回"",所以只有一个默认前缀;根据需要实现更复杂的版本。

这确实会对Sun类产生依赖性,这是由JAXB引起的问题。请查看this other post。底部的答案显示了如何修改package-info.java以实现相同目标。

答案 1 :(得分:1)

或者,您可以使用Metro JAXB,而不是使用专有的MOXy JAXB扩展名。 MOXy将使用@XmlSchema包级别注释中定义的名称空间前缀。

有关详细信息,请参阅: