使用 JAXB 获取 XML 子节点的值
Posted
技术标签:
【中文标题】使用 JAXB 获取 XML 子节点的值【英文标题】:getting the value of an XML subnode using JAXB 【发布时间】:2021-10-23 04:42:43 【问题描述】:我正在尝试使用 JAXB 映射此 XML 文件并获取 CODE
元素的值。最终,完整的 XML 文件将包含许多收费代码块,我需要提取不同标签的所有值,但现在我只想设法获得一个值。
XML:
<?xml version="1.0" encoding="utf-8" ?>
<tpDoc>
<tpCTRL>
<DocID>CHARGE CODES</DocID>
<SenderID>IES</SenderID>
</tpCTRL>
<PAYLOAD>
<CHARGE_CODE>
<CODE>TEST</CODE>
<DESCRIPTION>M Test</DESCRIPTION>
<SALES_ACCOUNT>34535</SALES_ACCOUNT>
<COSTS_ACCOUNT>500056756745</COSTS_ACCOUNT>
</CHARGE_CODE>
</PAYLOAD>
</tpDoc>
这是编组代码:
public class XMLtoJava
public static void main(String[] args) throws JAXBException
File inputFile = new File("C:\\Users\\Inbar\\OneDrive\\OneDrive - alfacloud.co.il\\MSF\\Developments\\OrdertoCashThirdPartyProcess(B2B)\\MSF XMLFiles\\ChargeCodesSmall.XML");
JAXBContext jaxbContext = JAXBContext.newInstance(CC.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
CC chargeCode = (CC) unmarshaller.unmarshal(inputFile);
System.out.println();
System.out.println(chargeCode.getCode());
班级:
@XmlRootElement(name="tpDoc")
@XmlAccessorType(XmlAccessType.FIELD)
public class CC
@XmlElement(name="CODE")
private String code;
@XmlElement(name="DESCRIPTION")
private String description;
@XmlElement(name="SALES_ACCOUNT")
private String salesAccount;
@XmlElement(name="COSTS_ACCOUNT")
private String costsAccount;
public String getCode()
return code;
但是,我得到的只是空值。我做错了什么?
【问题讨论】:
tpDoc
没有您在CC
中指定的字段。它有一个PAYLOAD
,其中包含一个CODE
和其他元素。换句话说,您在CC
中的定义与 XML 结构不匹配。
@MarkRotteveel 那么我想以某种方式创建另一个名为 payload 的类还是我可以以某种方式告诉这个 tpdoc 类正确的子结构?换句话说,在创建尽可能少的类的同时,我该怎么做才能解决这个问题。
您可以使用this 等在线工具将示例XML 文件转换为XSD。然后您可以使用xjc
工具(与Java 8 捆绑在一起,或者也可以使用here)使用该XSD 来生成表示XML 结构所需的Java 类。
建议:在生成 Java 类时,请确保您的示例 XML 包含多个 <CHARGE_CODE>
部分,因为这最终是您需要的,并且与 XML 相比,这将改变 Java 的结构只有一个 <CHARGE_CODE>
条目的示例。
【参考方案1】:
这应该对你有用,你应该能够得到任何值。我已将Project Lombok
用于Getter and Setter methods
。另外,跳过了tpCTRL
的 POJO,您需要添加它们
XML:
<?xml version="1.0" encoding="utf-8" ?>
<tpDoc>
<tpCTRL>
<DocID>CHARGE CODES</DocID>
<SenderID>IES</SenderID>
</tpCTRL>
<PAYLOAD>
<CHARGE_CODE>
<CODE>TEST</CODE>
<DESCRIPTION>M Test</DESCRIPTION>
<SALES_ACCOUNT>34535</SALES_ACCOUNT>
<COSTS_ACCOUNT>500056756745</COSTS_ACCOUNT>
</CHARGE_CODE>
</PAYLOAD>
</tpDoc>
tpDoc:
@XmlRootElement(name = "tpDoc")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class tpDoc
@XmlElement(name="PAYLOAD")
private Payload payload;
有效载荷;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Payload
@XmlElement(name="CHARGE_CODE")
private ChargeCode chargeCode;
收费代码;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class ChargeCode
private String CODE;
private String DESCRIPTION;
private String SALES_ACCOUNT;
private String COSTS_ACCOUNT;
主要:
public class Main
public static void main(String[] args) throws JAXBException, XMLStreamException
final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("sample.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(tpDoc.class).createUnmarshaller();
final tpDoc tpDoc = unmarshaller.unmarshal(xmlStreamReader, tpDoc.class).getValue();
System.out.println(tpDoc.toString());
System.out.println(tpDoc.getPayload().getChargeCode().getCODE());
System.out.println(tpDoc.getPayload().getChargeCode().getCOSTS_ACCOUNT());
Marshaller marshaller = JAXBContext.newInstance(tpDoc.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(tpDoc, System.out);
下面是输出;
tpDoc(payload=Payload(chargeCode=ChargeCode(CODE=TEST, DESCRIPTION=M Test, SALES_ACCOUNT=34535, COSTS_ACCOUNT=500056756745)))
TEST
500056756745
<tpDoc>
<PAYLOAD>
<CHARGE_CODE>
<CODE>TEST</CODE>
<DESCRIPTION>M Test</DESCRIPTION>
<SALES_ACCOUNT>34535</SALES_ACCOUNT>
<COSTS_ACCOUNT>500056756745</COSTS_ACCOUNT>
</CHARGE_CODE>
</PAYLOAD>
</tpDoc>
【讨论】:
伟大的 sutff,谢谢。我想知道。如果我需要将我提取的值用于其他事情,比如验证与数据库等等......我是否在解组类中为这些数据编写 getter 以用于其他包?@Data
每个类的注释来自Project Lombok
,它具有Getter
和Setter
,因此如果您使用Poject Lombok
,则无需编写任何额外的Getter
在各自的POJO Classes
上使用@Data
。乐意效劳。如果对您有帮助,请点赞并接受答案。
也接受答案?您需要做的就是点击我的答案旁边的CHECK
按钮,然后点击我的答案旁边的^
符号:***.com/help/someone-answers以上是关于使用 JAXB 获取 XML 子节点的值的主要内容,如果未能解决你的问题,请参考以下文章