JAXB, xs: any и targetNamespace - PullRequest
       0

JAXB, xs: any и targetNamespace

1 голос
/ 27 сентября 2010

У меня есть 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 из определения пользователя, он удалит ns2 из сгенерированного XML.

Как я могу сказать JAXB, что оба targetNamespace и aa - это одно и то же пространство имен, поэтому оно не включает оба?

Ответы [ 2 ]

3 голосов
/ 28 сентября 2010

Вы можете попытаться использовать 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.Пожалуйста, просмотрите этот другой пост .Ответ внизу показывает, как изменить package-info.java для достижения того же.

1 голос
/ 28 сентября 2010

В качестве альтернативы, вместо использования проприетарного расширения Metro JAXB , вы можете использовать MOXy JAXB .MOXy будет использовать префикс пространства имен, определенный в аннотации уровня пакета @XmlSchema.

Для получения дополнительной информации см .:

...