1

I used the XWiki Schema Definition to create with the Eclipse XJC Binding Compiler an object class model. In the package-info.java the following namespace is created

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.xwiki.org", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.xwiki.rest.model.jaxb;

When i read an Example from an HttpResponse

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<page xmlns="http://www.xwiki.org">
   <link rel="http://www.xwiki.org/rel/space" href="http://localhost:8080/xwiki/rest/wikis/xwiki/spaces/Main" />
   ...
</page>

with JAXB

try {
   JAXBContext context = JAXBContext.newInstance(org.xwiki.rest.model.jaxb.Page.class);
   Unmarshaller unmarshaller = context.createUnmarshaller();
   InputStream is = new FileInputStream(new File("request_result.xml"));
   Page page = (Page) unmarshaller.unmarshal(is);
} catch (JAXBException e) {
   e.printStackTrace();
} catch (FileNotFoundException e) {
   e.printStackTrace();
}

the Exception

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.xwiki.org", local:"page"). Expected elements are <{http://www.xwiki.org}attachments>,<{http://www.xwiki.org}classes>,<{http://www.xwiki.org}comments>,<{http://www.xwiki.org}history>,<{http://www.xwiki.org}objects>,<{http://www.xwiki.org}pages>,<{http://www.xwiki.org}properties>,<{http://www.xwiki.org}searchResults>,<{http://www.xwiki.org}spaces>,<{http://www.xwiki.org}tags>,<{http://www.xwiki.org}wikis>
   at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:648)
   at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:236)
   ...

is thrown.

I don't understand what's wrong, because the namespace seems correct. What i have to change to get a working XWiki RESTful API?

Matthias Wegner
  • 303
  • 4
  • 18

1 Answers1

1

The mapping for the page element is probably on an @XmlElementDecl annotation on the generated ObjectFactory class. You could change your JAXBContext creation to the following to pick that up:

JAXBContext context = JAXBContext.newInstance(org.xwiki.rest.model.jaxb.ObjectFactory.class);

Or you could just create the JAXBContext on the package name of the generated model:

JAXBContext context = JAXBContext.newInstance("org.xwiki.rest.model.jaxb");

UPDATE

Thanks, that helped a little. Now i get Exception in thread "main" java.lang.ClassCastException: javax.xml.bind.JAXBElement cannot be cast to org.xwiki.rest.model.jaxb.Page.

The result you get when the root is annotated with @XmlElementDecl instead of @XmlRootElement is an instance of JAXBElement that contains an instance of the domain class.

You can do the following:

JAXBElement<Page> jaxbElement = (JAXBElement<Page>) unmarshaller.unmarshal(is);
Page page = jaxbElement.getValue();

Or:

Page page = (Page) JAXBIntrospector.getValue(unmarshaller.unmarshal(is));

For More Information

I have written more about this particular use case on my blog:

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • 1
    Thanks, that helped a little. Now i get _Exception in thread "main" java.lang.ClassCastException: javax.xml.bind.JAXBElement cannot be cast to org.xwiki.rest.model.jaxb.Page_. I put the class at http://www.file-upload.net/download-8975023/Page.java.html. The Object Factory is here http://www.file-upload.net/download-8975019/ObjectFactory.java.html – Matthias Wegner May 29 '14 at 19:05