java - 无法在 Java 中使用 Jaxb 仅提取选定的标签值

标签 java xml jaxb unmarshalling

我有一个非常大的 XML 字符串。我在这里仅发布 XML 对象的一部分。我正在尝试将此 XML 转换为 Java 对象。我的第一个问题是,我是否需要创建全部 XML 标记值的 Java 对象,或者我可以创建仅选定的内部 XML 对象的 Java 对象吗?请找到我的 XML 字符串。

<DATAPACKET REQUEST-ID = "2">
<HEADER>
    <RESPONSE-TYPE CODE="1" DESCRIPTION="Response DataPacket"/>
    <SEARCH-RESULT-LIST>
        <SEARCH-RESULT-ITEM>
            <NAME MATCHED="TRUE"/>              
        </SEARCH-RESULT-ITEM>
    </SEARCH-RESULT-LIST>
</HEADER>
<BODY>
    <CONS_SCORE>
        <SCORE>0</SCORE>
        <REASON1>
            <HEADER></HEADER>
            <DESCRIPTION></DESCRIPTION>
        </REASON1>
        <REASON2>
            <HEADER></HEADER>
            <DESCRIPTION></DESCRIPTION>
        </REASON2>
        <REASON3>
            <HEADER></HEADER>
            <DESCRIPTION></DESCRIPTION>
        </REASON3>
        <REASON4>
            <HEADER></HEADER>
            <DESCRIPTION></DESCRIPTION>
        </REASON4>
    </CONS_SCORE>
    <CONSUMER_PROFILE2>
        <CONSUMER_DETAILS2>
            <RUID>1234</RUID>
            <NAME>ABC</NAME>
            <DATE_OF_BIRTH>1980-03-03T00:00:00+03:00</DATE_OF_BIRTH>
            <GENDER>001</GENDER>                
        </CONSUMER_DETAILS2>
        <ID_DETAILS2>
            <SLNO>1</SLNO>
            <SOURCE_ID>001</SOURCE_ID>
            <ID_VALUE>2806</ID_VALUE>
            <EXP_DATE>2018-07-13T00:00:00+03:00</EXP_DATE>              
        </ID_DETAILS2>
    </CONSUMER_PROFILE2>
    </BODY>
</DATAPACKET>

在上面的对象中,我只想获取 CONSUMER_PROFILE2 对象。这是我的 Dto 类

@XmlRootElement(name = "DATAPACKET")
public class ConsumerProfileDto {

private ConsumerDetailsDto CONSUMER_DETAILS2;

private IdDetailsDto ID_DETAILS2;

public ConsumerDetailsDto getCONSUMER_DETAILS2() {
    return CONSUMER_DETAILS2;
}

public void setCONSUMER_DETAILS2(ConsumerDetailsDto cONSUMER_DETAILS2) {
    CONSUMER_DETAILS2 = cONSUMER_DETAILS2;
}

public IdDetailsDto getID_DETAILS2() {
    return ID_DETAILS2;
}

public void setID_DETAILS2(IdDetailsDto iD_DETAILS2) {
    ID_DETAILS2 = iD_DETAILS2;
}
}

CONSUMER_DETAILS2 类

@XmlRootElement(name = "CONSUMER_DETAILS2")
public class ConsumerDetailsDto {

private String NAME;
private String DATE_OF_BIRTH;
private String GENDER;
private String NATIONALITY;
public String getNAME() {
    return NAME;
}
public void setNAME(String nAME) {
    NAME = nAME;
}
public String getDATE_OF_BIRTH() {
    return DATE_OF_BIRTH;
}
public void setDATE_OF_BIRTH(String dATE_OF_BIRTH) {
    DATE_OF_BIRTH = dATE_OF_BIRTH;
}
public String getGENDER() {
    return GENDER;
}
public void setGENDER(String gENDER) {
    GENDER = gENDER;
}
public String getNATIONALITY() {
    return NATIONALITY;
}
public void setNATIONALITY(String nATIONALITY) {
    NATIONALITY = nATIONALITY;
}

这是解码代码

JAXBContext jaxbContext = JAXBContext.newInstance(ConsumerProfileDto.class);  

    StringReader reader = new StringReader(responseXML);

    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();  
    ConsumerDetailsDto que= (ConsumerDetailsDto) jaxbUnmarshaller.unmarshal(reader);  

    System.out.println(que.getDATE_OF_BIRTH());  
    System.out.println(que.getGENDER());;
    System.out.println(que.getNAME());

附注

我使用了 DocumentBuilder,并且可以使用它获取值。但是,我想使用 Jaxb 进行提取。

最佳答案

您无法将反射(reflect)您感兴趣的 XML 元素的 Java 类注释为 @XmlRootElement。您必须在 Java 中镜像所有 XML 元素,从 XML 文件中的最顶层元素 (DATAPACKET) 到您感兴趣的路径中的最低元素(CONSUMER_DETAILS2 和 ID_DETAILS2),即使您只对其中的某些元素感兴趣。

我假设运算符(operator)对 RUID 不感兴趣(因为类 CONSUMER_DETAILS2 不包含此 XML 元素的字段),并且不会从此 XML 加载字段 NATIONALITY。

如果问题的输入 XML 位于名为 input2.xml 的文件中,那么我将拥有以下 Java 类:

数据包

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "DATAPACKET")
public class DataPacket {

    @XmlAttribute(name = "REQUEST_ID")
    private int REQUEST_ID;

    @XmlElement(name ="BODY")
    private Body BODY;

    public DataPacket(){}

    public int getREQUEST_ID() {
        return REQUEST_ID;
    }

    public void setREQUEST_ID(int REQUEST_ID) {
        this.REQUEST_ID = REQUEST_ID;
    }

    public Body getBODY() {
        return BODY;
    }

    public void setBODY(Body BODY) {
        this.BODY = BODY;
    }
}

正文

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.NONE)
class Body {

    @XmlElement(name = "CONSUMER_PROFILE2")
    private ConsumerProfile profile;

    public Body(){}

    public ConsumerProfile getProfile() {
        return profile;
    }

    public void setProfile(ConsumerProfile profile) {
        this.profile = profile;
    }
}

消费者概况

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.NONE)
public class ConsumerProfile {

    @XmlElement(name = "CONSUMER_DETAILS2")
    private ConsumerDetails CONSUMER_DETAILS2;

    @XmlElement(name = "ID_DETAILS2")
    private IdDetails ID_DETAILS2;

    public ConsumerProfile(){}

    public ConsumerDetails getCONSUMER_DETAILS2() {
        return CONSUMER_DETAILS2;
    }

    public void setCONSUMER_DETAILS2(ConsumerDetails cONSUMER_DETAILS2) {
        CONSUMER_DETAILS2 = cONSUMER_DETAILS2;
    }

    public IdDetails getID_DETAILS2() {
        return ID_DETAILS2;
    }

    public void setID_DETAILS2(IdDetails iD_DETAILS2) {
        ID_DETAILS2 = iD_DETAILS2;
    }
}

消费者详细信息

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.NONE)
class ConsumerDetails {

    @XmlElement(name="NAME")
    private String NAME;

    @XmlElement(name="DATE_OF_BIRTH")
    private String DATE_OF_BIRTH;

    @XmlElement(name="GENDER")
    private String GENDER;

    private String NATIONALITY;

    public ConsumerDetails(){}

    public String getNAME() {
        return NAME;
    }
    public void setNAME(String nAME) {
        NAME = nAME;
    }
    public String getDATE_OF_BIRTH() {
        return DATE_OF_BIRTH;
    }
    public void setDATE_OF_BIRTH(String dATE_OF_BIRTH) {
        DATE_OF_BIRTH = dATE_OF_BIRTH;
    }
    public String getGENDER() {
        return GENDER;
    }
    public void setGENDER(String gENDER) {
        GENDER = gENDER;
    }
    public String getNATIONALITY() {
        return NATIONALITY;
    }
    public void setNATIONALITY(String nATIONALITY) {
        NATIONALITY = nATIONALITY;
    }
}

ID详细信息

package test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.NONE)
class IdDetails {

    @XmlElement(name="SLNO")
    private int SLNO;

    @XmlElement(name="SOURCE_ID")
    private String SOURCE_ID;

    @XmlElement(name="ID_VALUE")
    private int ID_VALUE;

    @XmlElement(name="EXP_DATE")
    private String EXP_DATE;

    public IdDetails(){}

    public int getSLNO() {
        return SLNO;
    }

    public void setSLNO(int SLNO) {
        this.SLNO = SLNO;
    }

    public String getSOURCE_ID() {
        return SOURCE_ID;
    }

    public void setSOURCE_ID(String SOURCE_ID) {
        this.SOURCE_ID = SOURCE_ID;
    }

    public int getID_VALUE() {
        return ID_VALUE;
    }

    public void setID_VALUE(int ID_VALUE) {
        this.ID_VALUE = ID_VALUE;
    }

    public String getEXP_DATE() {
        return EXP_DATE;
    }

    public void setEXP_DATE(String EXP_DATE) {
        this.EXP_DATE = EXP_DATE;
    }
}

此外,在同一个“测试”包中,jaxb.in​​dex 文件包含:

DataPacket
ConsumerProfile
ConsumerDetails
IdDetails

然后,当使用这个 Test 类进行测试时:

package test;

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class Test {

    public static void main(String[] args) {
        try{
            JAXBContext jc = JAXBContext.newInstance(DataPacket.class);

            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("input2.xml");
            DataPacket dp = (DataPacket) unmarshaller.unmarshal(xml);
            Body body = dp.getBODY();
            ConsumerProfile profile = body.getProfile();
            ConsumerDetails consumerDetail = profile.getCONSUMER_DETAILS2();
            IdDetails idDetails = profile.getID_DETAILS2();
            System.out.println("ConsumerDetails name:"+consumerDetail.getNAME()+
                               " date of birth:"+consumerDetail.getDATE_OF_BIRTH()+
                               " gender:"+consumerDetail.getGENDER()+
                               "IdDetails SLNO:"+idDetails.getSLNO()+
                                " SOURCE_ID:"+idDetails.getSOURCE_ID()+
                                " ID_VALUE:"+idDetails.getID_VALUE()+
                                " EXP_DATE:"+idDetails.getEXP_DATE());
        }
        catch(JAXBException e){
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }
}

关于java - 无法在 Java 中使用 Jaxb 仅提取选定的标签值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46463740/

相关文章:

java - 如何优化java中的嵌套for循环?

java - 通过网络路径读取文件

java - 可怕的 java.lang.NoClassDefFoundError

java - 恢复h2数据库

Android - 缺少父主题?

java - 如何使用 Apache Camel 从 xml 中提取数据并将其保存到数据库

xml - Powershell:如何将 Format-Table 与 XML 数据一起使用

xml - "Invalid character in entity name"升级到 {N} 6.3 后 && 在条件

java - JAXB 可映射 XML 元素

java - JAXB 解码 xml 而不使用 package-info.java