Unmarshalling为在xml中具有命名空间的子字段提供空值

问题描述 投票:1回答:1

由于我正在使用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);
    }
}
java xml jaxb unmarshalling regression-testing
1个回答
1
投票

问题出在你的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);
}

但在我看来,你根本不需要SAXParserFactorySAXSource的东西。您可以像这样简化方法:

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

上面的两种方法都适用于其余的代码,即类nickNameInformation正确设置为XML输入中给出的"[email protected]"

© www.soinside.com 2019 - 2024. All rights reserved.