JAXB to unmarshall <string>foobar</string>

16,287

Solution 1

You need to write an object model that conforms to your XML structure, and tell JAXB to unmarshal on to that. Your example may look simple, but it's not what JAXB is for.

Try something like this:

@XmlRootElement(name="string", namespace="blah")
public class MyString {
   @XmlValue
   String value;
}

JAXBContext context = JAXBContext.newInstance(MyString.class);
MyString myString = (MyString) context.createUnmarshaller().unmarshal(...);

This will unmarshal the XML <string xmlns="blah">foobar</string>. Change the namespace accordingly. If you have many namespaces, then JAXB isn't really the tool for you.

Solution 2

I was surprised by this, but the following seems to work:

final String xmlString = "<string>value</string>";
final StringReader xmlReader = new StringReader(xmlString);
final StreamSource xmlSource = new StreamSource(xmlReader);
final JAXBContext jaxbContext = JAXBContext.newInstance(String.class);
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
final String stringValue = unmarshaller.unmarshal(xmlSource, String.class).getValue();

Is that what you were looking for?

Solution 3

When you're using JAXB, you need to build the code around an XML schema. That is, if you have a file, say foo.xsd, you need to run it through the xjc compiler (in JDK 6 by default, otherwise you can download JAXB 2 and use that). That will read through the schema and generate the Java bean and associated ObjectFactory classes with the elements in the schema. The Java bean classes will look like regular POJOs with annotations. The ObjectFactory classes are needed by the JAXB implementation to convert the XML into the corresponding Java bean. This explains your ObjectFactory missing exception.

So it's not hard, but there is some leg work involved. We use it for one of our production applications and it's great. I see myself using it more now that it's part of the JDK.

Share:
16,287
Admin
Author by

Admin

Updated on June 20, 2022

Comments

  • Admin
    Admin almost 2 years

    Greetings! I have a server returning XML content to my client that looks like this:

    <string xmlns="...">foobar</string>
    

    I'm new to JAXB and have gotten a lot of stuff working, except this. I thought it would be pretty easy to marshal and unmarshal this to and from a String. It took a while, but I finally figured out how to marshal this as

        public static String ToXML(String s) throws Exception
        {
            JAXBContext context = JAXBContext.newInstance(String.class);
            Marshaller marshaller = context.createMarshaller();
            StringWriter sw = new StringWriter();
            marshaller.marshal(new JAXBElement(new QName("", "String"), String.class, s), sw);
    
            return sw.toString();
        }
    

    So my question is, how to I unmarshal this? It cannot be annotated as a root element. I cannot use java.lang as the package to create a new instance of a JAXBContext (I get an ObjectFactory missing exception).

    Any wisdom to impart? This can't be that hard, right?

  • skaffman
    skaffman over 14 years
    An XML Schema is entirely optional with JAXB. It's perfectly acceptable to hand-annotate your own object model.
  • Andy Gherna
    Andy Gherna over 14 years
    True, but having a schema-generated set of objects ensures correctness in the document (the document can be validated against the schema) and the Java objects (it's easy to miss a field). You can repeat the process across multiple applications and machines too.