我有一个类 Person 具有属性名称和地址。我在 XML 中显示它。从 XML 解组时,可以分别获取名称和地址的行号。我尝试使用定位器。但它不提供单独的行号。
问问题
2395 次
2 回答
3
EclipseLink JAXB (MOXy)和JAXB 参考实现都有自己的@XmlLocation
注释来支持这个用例。这允许您将与对象对应的 XML 元素上的位置存储为org.xml.sax.Locator
. 由于我是 MOXy 负责人,我将演示如何使用 MOXy:
人
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
@XmlJavaTypeAdapter(value=StringAdapter.class)
String name;
Address address;
@XmlLocation
Locator locator;
}
地址
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;
public class Address {
@XmlJavaTypeAdapter(value=StringAdapter.class)
private String street;
@XmlLocation
Locator locator;
}
字符串适配器
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.eclipse.persistence.oxm.annotations.XmlLocation;
import org.xml.sax.Locator;
public class StringAdapter extends XmlAdapter<StringAdapter.AdaptedString, String> {
public static class AdaptedString {
@XmlValue
public String value;
@XmlLocation
@XmlTransient
Locator locator;
}
@Override
public String unmarshal(AdaptedString v) throws Exception {
System.out.println(v.value + " " + v.locator.getLineNumber());
return v.value;
}
@Override
public AdaptedString marshal(String v) throws Exception {
AdaptedString adaptedString = new AdaptedString();
adaptedString.value = v;
return adaptedString;
}
}
jaxb.properties
要将 MOXy 指定为您的 JAXB 提供程序,您需要包含一个jaxb.properties
在与您的域模型相同的包中调用的文件,其中包含以下条目。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
演示
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Person.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum14455596/input.xml");
Person person = (Person) unmarshaller.unmarshal(xml);
System.out.println("Person: " + person.locator.getLineNumber());
System.out.println("Address: " + person.address.locator.getLineNumber());
}
}
输出
Jane Doe 3
1 A Street 5
Person: 2
Address: 4
于 2013-01-22T10:55:19.100 回答
2
您可以利用 StAXStreamReaderDelegate
并执行以下操作:
演示
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Person.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource source = new StreamSource("src/forum14455596/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(source);
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
if(isStartElement()) {
System.out.println(localName + " " + this.getLocation().getLineNumber());
}
return localName;
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.unmarshal(xsr);
}
}
人
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
private String name;
private String address;
}
输入.xml
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>Jane Doe</name>
<address>1 A Street</address>
</person>
输出
person 2
name 3
address 4
于 2013-01-22T10:21:56.417 回答