Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
If there is another Java XML framework that can generate classes from
an XSD file and support locator data, then I'm willing to switch.
JAXB can generate classes from an XML schema, and below are a couple of ways you could get the location information. For a comparison of JAXB and XMLBeans see:
OPTION #1 - StAX and Unmarshaller.Listener
Demo
package forum10241929;
import java.io.File;
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 {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource(new File("src/forum10241929/input.xml")));
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setListener(new LocationListener(xsr));
Customer customer = (Customer) unmarshaller.unmarshal(xsr);
}
private static class LocationListener extends Unmarshaller.Listener {
private XMLStreamReader xsr;
public LocationListener(XMLStreamReader xsr) {
this.xsr = xsr;
}
@Override
public void afterUnmarshal(Object target, Object parent) {
log("End", target);
}
@Override
public void beforeUnmarshal(Object target, Object parent) {
log("Start", target);
}
private void log(String event, Object target) {
System.out.print(event);
System.out.print(" ");
System.out.print(target);
System.out.print(" [");
Location location = xsr.getLocation();
System.out.print(location.getLineNumber());
System.out.print(",");
System.out.print(location.getColumnNumber());
System.out.println("]");
}
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<name>Jane Doe</name>
<address>
<street>1 A Street</street>
</address>
</customer>
Output
Start forum10241929.Customer@144aa0ce [2,11]
Start forum10241929.Address@19e3cd51 [4,14]
End forum10241929.Address@19e3cd51 [6,15]
End forum10241929.Customer@144aa0ce [7,12]
Customer
package forum10241929;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer {
private String name;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address
package forum10241929;
public class Address {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
OPTION #2 - @XmlLocation
There is a JAXB extension that is supported by both EclipseLink JAXB (MOXy) and the reference implementation called @XmlLocation
(below is an Example using MOXy). This will only capture the start location.
package forum10241929;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;
@XmlRootElement
public class Customer {
private String name;
private Address address;
@XmlLocation
private Locator location;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}