Question

I am facing an issue while doing the unmarshal using JAXB of an input XML doc. The XML doc looks like

<?xml version="1.0" encoding="windows-1252"?>
<!DOCTYPE Power SYSTEM "http://someuri/TestModel_v9.dtd">
<Power>
    <Data>
    </Data>
    <Control>
        <Inp1>MyInp</Inp1>
        <Inp2>MyInp</Inp2>
    </Control>
</Power>

I have already generated JAXB classes and able to access all the unmarshalled data except DOCTYPE. I need the DOCTYPE section also as part of unmarshalled data. I am using Unmarshaller.unmarshal method in JAXB. A snippet of unmarshalling using JAXB.

File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Power.class);

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Power power= (Power) jaxbUnmarshaller.unmarshal(file);

Any idea how I can achieve that? If JAXB is not able to do this, please suggest any alternative work around which I can use along with JAXB.

Thanks, Bhaskar

Was it helpful?

Solution

Here is how you can capture the doctype information if you use JAXB with StAX.

XMLResolver (MyXMLResolver)

Here is an implementation of XMLResolver you can use to capture the doctype information.

import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamException;

public class MyXMLResolver implements XMLResolver {

    private String publicID;
    private String systemID;
    private String baseURI;
    private String namespace;

    @Override
    public Object resolveEntity(String publicID, String systemID,
            String baseURI, String namespace) throws XMLStreamException {
        this.publicID = publicID;
        this.systemID = systemID;
        this.baseURI = baseURI;
        this.namespace = namespace;
        return null;
    }

    public String getPublicID() {
        return publicID;
    }

    public String getSystemID() {
        return systemID;
    }

    public String getBaseURI() {
        return baseURI;
    }

    public String getNamespace() {
        return namespace;
    }

}

Demo

Here is how you leverage it in your use case:

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        MyXMLResolver resolver = new MyXMLResolver();
        xif.setXMLResolver(resolver);
        XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("input.xml"));

        JAXBContext jc = JAXBContext.newInstance(Power.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Power power = (Power) unmarshaller.unmarshal(xsr);

        System.out.println(resolver.getPublicID());
        System.out.println(resolver.getSystemID());
        System.out.println(resolver.getBaseURI());
        System.out.println(resolver.getNamespace());
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top