JAXB文件中未解组对象的位置

6

我有一些对象通过JAXB从XML文件中取消编组。在XML文件中(行和列),每个对象可能来自哪里,JAXB是否可以告诉我或以某种方式找出?

这些信息在某个时候是可用的,因为在模式验证错误期间,JAXB会将其提供给我。但我也希望对已验证的对象进行验证。

2个回答

13

您可以通过利用XMLStreamReaderUnmarshaller.Listener在JAXB中完成此操作:

演示

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

->

input.xml

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

输出

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

客户

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;
    }

}

地址

package forum383861;

public class Address {

}

更多信息


完美地工作了,非常感谢。唯一让我稍微意外的是它给出的是XML元素开头标签的结束位置而不是开始位置。但对于我的应用来说已经足够好了。 - lexicalscope
这似乎是在我的本地Tomcat上工作的解决方案,但在IBM WebSphere Application Server 8.5.5.10上,xsr.getLocation().getLineNumber()总是返回-1。我确保WAS使用了com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl。你能猜测是什么原因吗? - Nimtar

2
很抱歉,JAXB是建立在XML解析器之上的,它会构建一个逻辑表示你的XML文档的结构,而忘记了原始的字符串表示。验证步骤是在读取字符串时进行的,因此您的解析器能够给出错误消息,并告诉您错误的位置。JAXB只会绕过该错误消息。但是一旦XML被验证和解析,只有逻辑表示会存在。请注意保留HTML标签。

你可以利用 XMLStreamReaderUnmarshaller.Listener 来获得这种类型的支持:https://dev59.com/ZFrUa4cB1Zd3GeqPilFj#7081390 - bdoughan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接