由于我正在使用jdk 8u144,当我试图将xml取消标记为对象时,我获得了具有命名空间的字段的空值。尝试使用NamespaceFilter类,它将namespaceUri和addNamespace字段作为参数,但似乎它只适用于xml中的顶级字段。在这一点上有点困惑,可以做什么来解析具有命名空间的子字段。
将此字符串作为输入:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Company xmlns:ns2="http://www.openapplications.org/oagis/9">
<Staff>
<BasicInfo>
<Information>
<firstName>ABC</firstName>
<lastName>Primary</lastName>
<ns2:nickName>[email protected]</ns2:nickName>
</Information>
</BasicInfo>
</Staff>
</Company>
公司类:
@XmlRootElement(name="Company")
public class Company {
private List<Staff> staff;
public List<Staff> getStaff() {
return staff;
}
@XmlElement(name="Staff")
public void setStaff(List<Staff> staff) {
this.Staff = staff;
}
}
员工班级:
@XmlRootElement(name="Staff")
public class Staff {
private BasicInfo basicInfo;
public BasicInfo getBasicInfo() {
return basicInfo;
}
@XmlElement(name="BasicInfo")
public void setBasicInfo(BasicInfo basicInfo) {
this.basicInfo = basicInfo;
}
}
BasicInfo类:
@XmlRootElement(name="BasicInfo")
public class BasicInfo {
private Information information;
public Information getInformation() {
return information;
}
@XmlElement(name="Information")
public void setInformation(Information information) {
this.information = information;
}
}
信息类:
@XmlRootElement(name="Information")
public class Information {
private String firstName;
private String lastName;
private String nickName;
public String getFirstName() {
return firstName;
}
@XmlElement(name="firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
@XmlElement(name="lastName")
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getNickName() {
return nickName;
}
@XmlElement(namespace="http://www.openapplications.org/oagis/9", name="nickName")
public void setNickName(String nickName) {
this.nickName = nickName;
}
}
MyUnmarshaller类:
public class MyUnmarshaller {
public Company getComapany(String xmlString){
StringReader reader = new StringReader(xmlString);
JAXBContext jaxbContext = JAXBContext.newInstance(Company.class);
SAXParserFactory spf = SAXParserFactory.newInstance();
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(reader));
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (Company) jaxbUnmarshaller.unmarshal(xmlSource);
}
}
问题出在你的getComapany(String xmlString)
类MyUnmarshaller
方法中:你的SAXParserFactory
不知道命名空间。您需要在其上调用setNamespaceAware(true)
来解决问题:
public Company getComapany(String xmlString) throws Exception {
StringReader reader = new StringReader(xmlString);
JAXBContext jaxbContext = JAXBContext.newInstance(Company.class);
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true); // !!!!
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(reader));
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (Company) jaxbUnmarshaller.unmarshal(xmlSource);
}
但在我看来,你根本不需要SAXParserFactory
和SAXSource
的东西。您可以像这样简化方法:
public Company getComapany(String xmlString) throws Exception {
StringReader reader = new StringReader(xmlString);
JAXBContext jaxbContext = JAXBContext.newInstance(Company.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return (Company) jaxbUnmarshaller.unmarshal(reader);
}
上面的两种方法都适用于其余的代码,即类nickName
的Information
正确设置为XML输入中给出的"[email protected]"
。