开发者

JAXB location in file for unmarshalled objects

开发者 https://www.devze.com 2023-03-28 23:32 出处:网络
I have some objects being unmarshalled from an XML file by JAXB. Is it possible to have JAXB tell me or somehow find out where in the XML file (line and column) each object comes from?

I have some objects being unmarshalled from an XML file by JAXB. Is it possible to have JAXB tell me or somehow find out where in the XML file (line and column) each object comes from?

This information is available at some point, because JAXB gives it to me during schema validation errors开发者_运维知识库. But I would like to have it available for validated objects too.


You could do this in JAXB by leveraging an XMLStreamReader and an Unmarshaller.Listener:

Demo

package forum383861;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.Unmarshaller.Listener;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);


        XMLInputFactory xif = XMLInputFactory.newFactory();
        FileInputStream xml = new FileInputStream("src/forum383861/input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        LocationListener ll = new LocationListener(xsr);
        unmarshaller.setListener(ll);

        Customer customer = (Customer) unmarshaller.unmarshal(xsr);
        System.out.println(ll.getLocation(customer));
        System.out.println(ll.getLocation(customer.getAddress()));
    }

    private static class LocationListener extends Listener {

        private XMLStreamReader xsr;
        private Map<Object, Location> locations;

        public LocationListener(XMLStreamReader xsr) {
            this.xsr = xsr;
            this.locations = new HashMap<Object, Location>();
        }

        @Override
        public void beforeUnmarshal(Object target, Object parent) {
            locations.put(target, xsr.getLocation());
        }

        public Location getLocation(Object o) {
            return locations.get(o);
        }

    }

}

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<customer>
    <address/>
</customer>

Output

[row,col {unknown-source}]: [2,1]
[row,col {unknown-source}]: [3,5]

Customer

package forum383861;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Customer {

    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

}

Address

package forum383861;

public class Address {

}

For More Information

  • http://blog.bdoughan.com/2011/08/using-unmarshallerlistener-to-capture.html


I'm afraid not. JAXB builds on top of a XML parser, this one will have built up a logical representation of your XML document forgetting the original string representation of your document.

The validation step is done while your string is still read in, so your parser is able to give you an error message telling you the position of the error. JAXB will only bypass that error message. But as soon as the XML is validated and parsed, only the logical representation will exist.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号