Почему JAXB неправильно обрабатывает дочерние элементы с пространством имен?

Я использую JAXB с веб-службой CXF. Когда я прохожу:

<?xml version="1.0" ?><ns2:Optionen xmlns:ns2="http://test.at/ezustellung/global/20090501#">
<ns2:PdfAKonvertierung>true</ns2:PdfAKonvertierung><ns2:SignaturTyp>Adobe</ns2:SignaturTyp>
</ns2:Optionen>

для Unmarshaller свойства pdfAKonvertierung и signaturTyp являются нулевыми в моем объекте. Но если я пройду:

<?xml version="1.0" ?><ns2:Optionen xmlns:ns2="http://test.at/ezustellung/global/20090501#">
<PdfAKonvertierung>true</PdfAKonvertierung><SignaturTyp>Adobe</SignaturTyp>
</ns2:Optionen>

что является недействительным, согласно CXF Validator и википедии (перевод, на английском не нашел):

Дочерние элементы элемента с префиксом пространства имен не имеют автоматически одно и то же пространство имен, они также должны иметь префикс пространства имен.

Свойства установлены соответствующим образом. Может ли кто-нибудь обнаружить ошибку в моем коде или я нашел ошибку в реализации JAXB из Java 1.6?

Для справки, вот мой код:

 public class JaxbTests {
  @Test
  public void testOptionen() throws JAXBException, SAXException, IOException {
   JAXBContext context = JAXBContext.newInstance(Optionen.class);
   Unmarshaller unmarshaller = context.createUnmarshaller();
   ByteArrayInputStream is = new ByteArrayInputStream(
     // Does not work
     ("<?xml version=\"1.0\" ?><ns2:Optionen xmlns:ns2=\"http://test.at/ezustellung/global/20090501#\">" +
     "<ns2:PdfAKonvertierung>true</ns2:PdfAKonvertierung><ns2:SignaturTyp>Adobe</ns2:SignaturTyp>" +
     "</ns2:Optionen>").getBytes());

     // Works
 //    ("<?xml version=\"1.0\" ?><ns2:Optionen xmlns:ns2=\"http://test.at/ezustellung/global/20090501#\">" +
 //    "<PdfAKonvertierung>true</PdfAKonvertierung><SignaturTyp>Adobe</SignaturTyp>" +
 //    "</ns2:Optionen>").getBytes());
   Optionen opts = ((Optionen) unmarshaller.unmarshal(is));
   Assert.assertTrue(opts.isPdfAKonvertierung() == true);
   Assert.assertEquals(SignaturTypType.ADOBE, opts.getSignaturTyp());
  }
 }


 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "", propOrder = {
     "pdfAKonvertierung",
     "signaturTyp"
 })
 @XmlRootElement(name = "Optionen")
 public class Optionen {

     @XmlElement(name = "PdfAKonvertierung", defaultValue = "true")
     protected Boolean pdfAKonvertierung;
     @XmlElement(name = "SignaturTyp", defaultValue = "Adobe")
     protected SignaturTypType signaturTyp;

     public Optionen() {
      System.out.println("Optionen created");
     }
     public Boolean isPdfAKonvertierung() {
         return pdfAKonvertierung;
     }
     public void setPdfAKonvertierung(Boolean value) {
         this.pdfAKonvertierung = value;
     }
     public SignaturTypType getSignaturTyp() {
         return signaturTyp;
     }
     public void setSignaturTyp(SignaturTypType value) {
         this.signaturTyp = value;
     }

 }


 @XmlType(name = "SignaturTypType")
 @XmlEnum
 public enum SignaturTypType {

  @XmlEnumValue("Adobe")
  ADOBE("Adobe"), @XmlEnumValue("PDF-AS")
  PDF_AS("PDF-AS");
  private final String value;

  SignaturTypType(String v) {
   this.value = v;
  }

  public String value() {
   return this.value;
  }

  public static SignaturTypType fromValue(String v) {
   for (SignaturTypType c : SignaturTypType.values()) {
    if (c.value.equals(v)) {
     return c;
    }
   }
   throw new IllegalArgumentException(v);
  }

 }

пакет-info.java:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://test.at/ezustellung/global/20090501#")
package at.test.ezustellung.global._20090501_;

person Florian    schedule 08.03.2010    source источник


Ответы (2)


Решение (без изменения сгенерированных классов) проблемы состояло в том, чтобы убедиться, что

<xs:schema elementFormDefault="qualified">

атрибут присутствует и восстановить сопоставление jaxb, чтобы

elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED

попадает в package-info.java

person Florian    schedule 09.03.2010

Немного сложно прочитать ваш неправильно отформатированный код, но разве это не решит вашу проблему, если вы объявите свои элементы с правильным пространством имен, например. @XmlElement(namespace = "http://test.at/ezustellung/global/20090501#", name = "SignaturTyp", defaultValue = "Adobe")?

person jarnbjo    schedule 08.03.2010
comment
Это решило проблему. Большое спасибо! Изменение следующих строк в классе Optionen привело к правильному прохождению модульного теста: .at/ezustellung/global/20090501#, name = Optionen) public class Optionen { @XmlElement(namespace = test.at/ezustellung/global/20090501#, name = PdfAKonvertierung, defaultValue = true) protected Boolean pdfAKonvertierung; @XmlElement(namespace = test.at/ezustellung/global/20090501#, name = SignaturTyp , defaultValue = Adobe) защищенный SignaturTypType signaturTyp; - person Florian; 09.03.2010
comment
Извините, я здесь новенький, я принял ваш ответ, но не смог проголосовать, так как требуются кредиты. - person Florian; 09.03.2010
comment
Я не могу заставить xjc генерировать свойства пространства имен для аннотаций XmlElement/XmlRootElement. Любые идеи, как заставить это работать? - person Florian; 09.03.2010