【问题标题】:Unmarshalling gives null value for child fields having namespace in xml解组为在 xml 中具有命名空间的子字段提供空值
【发布时间】:2023-04-02 09:23:02
【问题描述】:

在使用 jdk 8u144 时,当我尝试将 xml 取消标记为对象时,我得到具有命名空间的字段的空值。尝试使用将 namespaceUri 和 addNamespace 字段作为参数的 NamespaceFilter 类,但似乎它仅适用于 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>sedembest@gmail.com</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;
    }
}

基本信息类:

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

【问题讨论】:

  • 我不知道这只是复制粘贴错误还是问题的一部分。 XML 示例的 &lt;lastName&gt;&lt;ns2:nickName&gt; 元素与 Information 类的 @XmlElements 不匹配(name = "LastName"name="NickName")。
  • 这是复制过去的错误。更正了问题

标签: java xml jaxb unmarshalling regression-testing


【解决方案1】:

问题出在MyUnmarshaller 类中的getComapany(String xmlString) 方法中: 您的 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 输入中给出的"sedembest@gmail.com"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    相关资源
    最近更新 更多