Search code examples
javaxml-parsingjaxb2

JAXB 2: unmarshalling xml without xml declaration


Good time!

I have an xml:

<fieldSet name="Test" desc="Test">
  <field name="id">
    <fieldinfo>
        <name>id</name>
        <type>String</type>
        <fieldsize>50</fieldsize>
    </fieldinfo>
    <validators />
  </field>
</fieldSet>

and I need to parse it using JAXB. I've tried this:

        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(CustomFieldSet.class);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

            StringReader reader = new StringReader(xml);
            CustomFieldSet fieldSet = (CustomFieldSet) unmarshaller.unmarshal(reader);

        } catch (Exception e) {
            logger.error(e.getMessage(), e); 
        }

where the CustomFieldSet class starts with:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "fieldSet")
public class CustomFieldSet {

@XmlAttribute(name = "name", required = true)
private String tableName;

@XmlAttribute(name = "desc", required = true)
private String tableDescription;

    ...

When the unmarshal() function is called the following exception is thrown:

javax.xml.bind.UnmarshalException - with linked exception: [org.xml.sax.SAXParseException: Content is not allowed in prolog.]

I think the problem is connected with the fact my xml doesn't contain an xml declaration (<?xml ...).

Does anybody know what is the workaround here?


Solution

  • JAXB (JSR-222) implementations do not require the XML header (i.e. <?xml version="1.0" encoding="UTF-8"?>), see below for an example. I suspect the there is something special about the XML string in your example.

    Java Model (Foo)

    package forum13341366;
    
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Foo {
    
        private String bar;
    
    }
    

    Demo Code

    package forum13341366;
    
    import java.io.StringReader;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Foo.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            StringReader xml = new StringReader("<foo><bar>Hello World</bar></foo>");
            Foo foo = (Foo) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(foo, System.out);
        }
    
    }
    

    Output

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <foo>
        <bar>Hello World</bar>
    </foo>