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

时间:2018-01-20 18:43:23

标签: java xml jaxb unmarshalling regression-testing

当我使用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>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;
    }
}

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

1 个答案:

答案 0 :(得分: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); } 一点都没有。您可以像这样简化方法:

nickName

上述两种方法都可以与其余代码一起使用, 即Information"sedembest@gmail.com" 正确设置为XML输入中给出的#include<iostream> #include<thread> #include<string> #include<mutex> #include<condition_variable> #include<unistd.h> #include <fstream> #define MAX_THREADS 50 using namespace std; thread *threads = new thread[MAX_THREADS]; condition_variable cv[MAX_THREADS]; mutex m1; int counter=0; int count_words_in_line(string line){ /*write your code here*/ return 1; } void printString(int tid, ifstream &inFile, int tcount) { unique_lock<mutex> lock(m1); while(1) { string line; inFile >> line; string a = ""; if(line==a)break; cv[(tid+1)%tcount].notify_one(); cv[tid].wait(lock); counter += count_words_in_line(line); } cv[(tid+1)%tcount].notify_one(); } int main(int argc, char** argv) { int tcount, ccount, k; std::ifstream inFile; string name; inFile.open("input.txt"); string str; tcount = 2; for(int i = 0; i < tcount; i++) { threads[i] = thread(printString, i, ref(inFile), tcount); } for (int i = 0; i < tcount; i++) threads[i].join(); cout << counter << endl; return 0; }