JAXB 解组问题(获取空列表)
JAXB Unmarshalling Issue (Getting empty list)
我正在尝试使用 JAXB api 解析以下 XML 文档,我想在其中解析包含多个 PROPERTYDATA 对象的 PROPERTYDATALIST 中的每个项目。在解组文档期间,我得到一个空列表。任何有关如何解决此问题的帮助将不胜感激。
<?xml version="1.0" encoding="UTF-8"?>
<FACILITY>
<ARRANGEMENTACTIVITY>
<ID>NEW</ID>
<CUSTOMER>500000030</CUSTOMER>
<CUSTOMERROLE>OWNER</CUSTOMERROLE>
<PROPERTYDATALIST>
<PROPERTYDATA>
<PROPERTY>FACOMMITMENT</PROPERTY>
<AMOUNT>600000</AMOUNT>
<TERM>5Y</TERM>
<MATURITYDATE>20261001</MATURITYDATE>
</PROPERTYDATA>
<PROPERTYDATA>
<PROPERTY>PRINCIPALINT</PROPERTY>
<FIXEDRATE>3.5</FIXEDRATE>
</PROPERTYDATA>
</PROPERTYDATALIST>
</ARRANGEMENTACTIVITY>
</FACILITY>
下面是我写的类解组XML文件
@XmlRootElement(name = "FACILITY")
@Data
@NoArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Facility {
@XmlElement(name = "ARRANGEMENTACTIVITY")
private ArrangementActivity arrangementActivity;
}
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(propOrder = {"id", "customer","propertyDataList", "application", "version", "operation"})
@Data
public class ArrangementActivity {
@XmlElement(name = "APPLICATION")
private String application;
@XmlElement(name = "VERSION")
private String version;
@XmlElement(name = "OPERATION")
private String operation;
@XmlElement(name = "ID")
private String id;
@XmlElement(name = "CUSTOMER")
private String customer;
@XmlElementWrapper(name = "PROPERTYDATALIST")
@XmlElement(name = "PROPERTYDATALIST")
private List<PropertyData> propertyDataList;
}
@XmlAccessorType(XmlAccessType.NONE)
@Data
@XmlType(propOrder = {"property", "amount", "term", "maturityDate", "fixedRate" })
public class PropertyData {
@XmlElement(name = "PROPERTY")
private String property;
@XmlElement(name = "AMOUNT")
private String amount;
@XmlElement(name = "TERM")
private String term;
@XmlElement(name = "MATURITYDATE")
private String maturityDate;
@XmlElement(name = "FIXEDRATE")
private String fixedRate;
}
public class JaxbExampleMain {
public static void main(String[] args) {
String fileSourcePath = // file path";
try {
File file = new File( fileSourcePath);
InputStream inputStream = new FileInputStream(file);
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Facility.class).createUnmarshaller();
final Facility facility = unmarshaller.unmarshal(xmlStreamReader, Facility.class).getValue();
System.out.println(facility.toString());
Marshaller marshaller = JAXBContext.newInstance(Facility.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(facility, System.out);
} catch(Exception e) {
e.printStackTrace();
}
}
}
使用上面的代码,我得到了除上面的 PropertyDataList 之外的所有元素。下面是输出
我发现你的代码有几个问题:
您已将多个根元素(ArrangementActivity、PropertyData)添加到您的 java classes。应该只有一个根元素(Facility)。
您在 proporder
中添加了一些属性,您应该包括所有属性,除非它们中的任何一个被标记为 transient
。
您的 XML 具有字段 capitalized
但您的字段是小写的,因此无法在 unmarshalling
期间直接分配值。您可以使用 @XmlElement
指定它将在 XML.
中的名称
(您要求的那个)您必须使用 @XmlElementWrapper
和 XmlElement
。
注意:我用过Project Lombok Getter & Setter
所以我没有在每个class
中使用Getter/Setter
方法
以下是解组和编组您的 XML 的代码:
Facility.class
@XmlRootElement(name = "FACILITY")
@Data
@NoArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Facility {
@XmlElement(name = "ARRANGEMENTACTIVITY")
private ArrangementActivity arrangementActivity;
}
ArrangementActivity.class
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(propOrder = {"id", "customer","propertyDataList","application","version","operation"})
@Data
public class ArrangementActivity {
@XmlElement(name = "APPLICATION")
private String application;
@XmlElement(name = "VERSION")
private String version;
@XmlElement(name = "OPERATION")
private String operation;
@XmlElement(name = "ID")
private String id;
@XmlElement(name = "CUSTOMER")
private String customer;
@XmlElementWrapper(name = "PROPERTYDATALIST")
@XmlElement(name = "PROPERTYDATA")
private List<PropertyData> propertyDataList;
}
PropertyData.class:
@XmlAccessorType(XmlAccessType.NONE)
@Data
@XmlType(propOrder = {"property", "amount", "term", "maturityDate", "fixedRate" })
public class PropertyData {
@XmlElement(name = "PROPERTY")
private String property;
@XmlElement(name = "AMOUNT")
private String amount;
@XmlElement(name = "TERM")
private String term;
@XmlElement(name = "MATURITYDATE")
private String maturityDate;
@XmlElement(name = "FIXEDRATE")
private String fixedRate;
}
JaxbExampleMain.class:
public class JaxbExampleMain {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("facility.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Facility.class).createUnmarshaller();
final Facility facility = unmarshaller.unmarshal(xmlStreamReader, Facility.class).getValue();
System.out.println(facility.toString());
Marshaller marshaller = JAXBContext.newInstance(Facility.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(facility, System.out);
}
}
以下是您得到的输出:
Facility(arrangementActivity=ArrangementActivity(application=null, version=null, operation=null, id=NEW, customer=500000030, propertyDataList=[PropertyData(property=FACOMMITMENT, amount=600000, term=5Y, maturityDate=20261001, fixedRate=null), PropertyData(property=PRINCIPALINT, amount=null, term=null, maturityDate=null, fixedRate=3.5)]))
<FACILITY>
<ARRANGEMENTACTIVITY>
<ID>NEW</ID>
<CUSTOMER>500000030</CUSTOMER>
<PROPERTYDATALIST>
<PROPERTYDATA>
<PROPERTY>FACOMMITMENT</PROPERTY>
<AMOUNT>600000</AMOUNT>
<TERM>5Y</TERM>
<MATURITYDATE>20261001</MATURITYDATE>
</PROPERTYDATA>
<PROPERTYDATA>
<PROPERTY>PRINCIPALINT</PROPERTY>
<FIXEDRATE>3.5</FIXEDRATE>
</PROPERTYDATA>
</PROPERTYDATALIST>
</ARRANGEMENTACTIVITY>
</FACILITY>
我正在尝试使用 JAXB api 解析以下 XML 文档,我想在其中解析包含多个 PROPERTYDATA 对象的 PROPERTYDATALIST 中的每个项目。在解组文档期间,我得到一个空列表。任何有关如何解决此问题的帮助将不胜感激。
<?xml version="1.0" encoding="UTF-8"?>
<FACILITY>
<ARRANGEMENTACTIVITY>
<ID>NEW</ID>
<CUSTOMER>500000030</CUSTOMER>
<CUSTOMERROLE>OWNER</CUSTOMERROLE>
<PROPERTYDATALIST>
<PROPERTYDATA>
<PROPERTY>FACOMMITMENT</PROPERTY>
<AMOUNT>600000</AMOUNT>
<TERM>5Y</TERM>
<MATURITYDATE>20261001</MATURITYDATE>
</PROPERTYDATA>
<PROPERTYDATA>
<PROPERTY>PRINCIPALINT</PROPERTY>
<FIXEDRATE>3.5</FIXEDRATE>
</PROPERTYDATA>
</PROPERTYDATALIST>
</ARRANGEMENTACTIVITY>
</FACILITY>
下面是我写的类解组XML文件
@XmlRootElement(name = "FACILITY")
@Data
@NoArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Facility {
@XmlElement(name = "ARRANGEMENTACTIVITY")
private ArrangementActivity arrangementActivity;
}
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(propOrder = {"id", "customer","propertyDataList", "application", "version", "operation"})
@Data
public class ArrangementActivity {
@XmlElement(name = "APPLICATION")
private String application;
@XmlElement(name = "VERSION")
private String version;
@XmlElement(name = "OPERATION")
private String operation;
@XmlElement(name = "ID")
private String id;
@XmlElement(name = "CUSTOMER")
private String customer;
@XmlElementWrapper(name = "PROPERTYDATALIST")
@XmlElement(name = "PROPERTYDATALIST")
private List<PropertyData> propertyDataList;
}
@XmlAccessorType(XmlAccessType.NONE)
@Data
@XmlType(propOrder = {"property", "amount", "term", "maturityDate", "fixedRate" })
public class PropertyData {
@XmlElement(name = "PROPERTY")
private String property;
@XmlElement(name = "AMOUNT")
private String amount;
@XmlElement(name = "TERM")
private String term;
@XmlElement(name = "MATURITYDATE")
private String maturityDate;
@XmlElement(name = "FIXEDRATE")
private String fixedRate;
}
public class JaxbExampleMain {
public static void main(String[] args) {
String fileSourcePath = // file path";
try {
File file = new File( fileSourcePath);
InputStream inputStream = new FileInputStream(file);
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Facility.class).createUnmarshaller();
final Facility facility = unmarshaller.unmarshal(xmlStreamReader, Facility.class).getValue();
System.out.println(facility.toString());
Marshaller marshaller = JAXBContext.newInstance(Facility.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(facility, System.out);
} catch(Exception e) {
e.printStackTrace();
}
}
}
使用上面的代码,我得到了除上面的 PropertyDataList 之外的所有元素。下面是输出
我发现你的代码有几个问题:
您已将多个根元素(ArrangementActivity、PropertyData)添加到您的 java classes。应该只有一个根元素(Facility)。
您在
proporder
中添加了一些属性,您应该包括所有属性,除非它们中的任何一个被标记为transient
。您的 XML 具有字段
中的名称capitalized
但您的字段是小写的,因此无法在unmarshalling
期间直接分配值。您可以使用@XmlElement
指定它将在 XML.(您要求的那个)您必须使用
@XmlElementWrapper
和XmlElement
。
注意:我用过Project Lombok Getter & Setter
所以我没有在每个class
Getter/Setter
方法
以下是解组和编组您的 XML 的代码:
Facility.class
@XmlRootElement(name = "FACILITY")
@Data
@NoArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
public class Facility {
@XmlElement(name = "ARRANGEMENTACTIVITY")
private ArrangementActivity arrangementActivity;
}
ArrangementActivity.class
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(propOrder = {"id", "customer","propertyDataList","application","version","operation"})
@Data
public class ArrangementActivity {
@XmlElement(name = "APPLICATION")
private String application;
@XmlElement(name = "VERSION")
private String version;
@XmlElement(name = "OPERATION")
private String operation;
@XmlElement(name = "ID")
private String id;
@XmlElement(name = "CUSTOMER")
private String customer;
@XmlElementWrapper(name = "PROPERTYDATALIST")
@XmlElement(name = "PROPERTYDATA")
private List<PropertyData> propertyDataList;
}
PropertyData.class:
@XmlAccessorType(XmlAccessType.NONE)
@Data
@XmlType(propOrder = {"property", "amount", "term", "maturityDate", "fixedRate" })
public class PropertyData {
@XmlElement(name = "PROPERTY")
private String property;
@XmlElement(name = "AMOUNT")
private String amount;
@XmlElement(name = "TERM")
private String term;
@XmlElement(name = "MATURITYDATE")
private String maturityDate;
@XmlElement(name = "FIXEDRATE")
private String fixedRate;
}
JaxbExampleMain.class:
public class JaxbExampleMain {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("facility.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Facility.class).createUnmarshaller();
final Facility facility = unmarshaller.unmarshal(xmlStreamReader, Facility.class).getValue();
System.out.println(facility.toString());
Marshaller marshaller = JAXBContext.newInstance(Facility.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(facility, System.out);
}
}
以下是您得到的输出:
Facility(arrangementActivity=ArrangementActivity(application=null, version=null, operation=null, id=NEW, customer=500000030, propertyDataList=[PropertyData(property=FACOMMITMENT, amount=600000, term=5Y, maturityDate=20261001, fixedRate=null), PropertyData(property=PRINCIPALINT, amount=null, term=null, maturityDate=null, fixedRate=3.5)]))
<FACILITY>
<ARRANGEMENTACTIVITY>
<ID>NEW</ID>
<CUSTOMER>500000030</CUSTOMER>
<PROPERTYDATALIST>
<PROPERTYDATA>
<PROPERTY>FACOMMITMENT</PROPERTY>
<AMOUNT>600000</AMOUNT>
<TERM>5Y</TERM>
<MATURITYDATE>20261001</MATURITYDATE>
</PROPERTYDATA>
<PROPERTYDATA>
<PROPERTY>PRINCIPALINT</PROPERTY>
<FIXEDRATE>3.5</FIXEDRATE>
</PROPERTYDATA>
</PROPERTYDATALIST>
</ARRANGEMENTACTIVITY>
</FACILITY>