Return 解组后为空列表
Return null and empty List after unmarsal
我使用 Jaxb 从 XSD Java classes 生成,我创建了 unmarshall 方法,但每个值 return 为空。请帮忙!
这是我的主Class:
try {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema xsdSchema = sf.newSchema(new File(%Here is the PATH% \CustomerAndOrders.xsd"));
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema(xsdSchema);
unmarshaller.setEventHandler(new MyValidationEventHandler());
File file = new File("%Here is the PATH% \ XMLTestFile.xml");
System.out.println(file.getName());
Root root = (Root) unmarshaller.unmarshal(file);
CustomerType orderT = new CustomerType();
Customers cust = new Customers();
for (CustomerType cT : cust.getCustomer()) {
System.out.println(cT.getContactName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
static class MyValidationEventHandler implements ValidationEventHandler {
public boolean handleEvent(ValidationEvent event) {
System.out.println("\nEVENT");
System.out.println("SEVERITY: " + event.getSeverity());
System.out.println("MESSAGE: " + event.getMessage());
System.out.println("LINKED EXCEPTION: " + event.getLinkedException());
System.out.println("LOCATOR");
System.out.println(" LINE NUMBER: " + event.getLocator().getLineNumber());
System.out.println(" COLUMN NUMBER: " + event.getLocator().getColumnNumber());
System.out.println(" OFFSET: " + event.getLocator().getOffset());
System.out.println(" OBJECT: " + event.getLocator().getObject());
System.out.println(" NODE: " + event.getLocator().getNode());
System.out.println(" URL: " + event.getLocator().getURL());
return true;
}
}
使用 Jaxb 生成 classes:
package XMLBeans;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"customers",
"orders"
})
@XmlRootElement(name = "Root")
public class Root {
@XmlElement(name = "Customers", required = true)
protected Root.Customers customers;
@XmlElement(name = "Orders", required = true)
protected Root.Orders orders;
/**
* Gets the value of the customers property.
*
* @return
* possible object is
* {@link Root.Customers }
*
*/
public Root.Customers getCustomers() {
return customers;
}
/**
* Sets the value of the customers property.
*
* @param value
* allowed object is
* {@link Root.Customers }
*
*/
public void setCustomers(Root.Customers value) {
this.customers = value;
}
/**
* Gets the value of the orders property.
*
* @return
* possible object is
* {@link Root.Orders }
*
*/
public Root.Orders getOrders() {
return orders;
}
/**
* Sets the value of the orders property.
*
* @param value
* allowed object is
* {@link Root.Orders }
*
*/
public void setOrders(Root.Orders value) {
this.orders = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Customer" type="{}CustomerType" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"customer"
})
public static class Customers {
@XmlElement(name = "Customer")
protected List<CustomerType> customer;
public List<CustomerType> getCustomer() {
if (customer == null) {
customer = new ArrayList<CustomerType>();
}
return this.customer;
}
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Order" type="{}OrderType" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"order"
})
public static class Orders {
@XmlElement(name = "Order")
protected List<OrderType> order;
/**
* Gets the value of the order property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the order property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getOrder().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link OrderType }
*
*
*/
public List<OrderType> getOrder() {
if (order == null) {
order = new ArrayList<OrderType>();
}
return this.order;
}
}
}
客户类型class
package XMLBeans;
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.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerType", propOrder = {
"companyName",
"contactName",
"contactTitle",
"phone",
"fax",
"fullAddress"
})
public class CustomerType {
@XmlElement(name = "CompanyName", required = true)
protected String companyName;
@XmlElement(name = "ContactName", required = true)
protected String contactName;
@XmlElement(name = "ContactTitle", required = true)
protected String contactTitle;
@XmlElement(name = "Phone", required = true)
protected String phone;
@XmlElement(name = "Fax")
protected String fax;
@XmlElement(name = "FullAddress", required = true)
protected AddressType fullAddress;
@XmlAttribute(name = "CustomerID")
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlSchemaType(name = "token")
protected String customerID;
/**
* Gets the value of the companyName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCompanyName() {
return companyName;
}
/**
* Sets the value of the companyName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCompanyName(String value) {
this.companyName = value;
}
/**
* Gets the value of the contactName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getContactName() {
return contactName;
}
/**
* Sets the value of the contactName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setContactName(String value) {
this.contactName = value;
}
/**
* Gets the value of the contactTitle property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getContactTitle() {
return contactTitle;
}
/**
* Sets the value of the contactTitle property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setContactTitle(String value) {
this.contactTitle = value;
}
/**
* Gets the value of the phone property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPhone() {
return phone;
}
/**
* Sets the value of the phone property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPhone(String value) {
this.phone = value;
}
/**
* Gets the value of the fax property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getFax() {
return fax;
}
/**
* Sets the value of the fax property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setFax(String value) {
this.fax = value;
}
/**
* Gets the value of the fullAddress property.
*
* @return
* possible object is
* {@link AddressType }
*
*/
public AddressType getFullAddress() {
return fullAddress;
}
/**
* Sets the value of the fullAddress property.
*
* @param value
* allowed object is
* {@link AddressType }
*
*/
public void setFullAddress(AddressType value) {
this.fullAddress = value;
}
/**
* Gets the value of the customerID property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCustomerID() {
return customerID;
}
/**
* Sets the value of the customerID property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCustomerID(String value) {
this.customerID = value;
}
}
这是我的样本 XML:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
</Customers>
<Orders>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-05-06T00:00:00</OrderDate>
<RequiredDate>1997-05-20T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-05-09T00:00:00">
<ShipVia>2</ShipVia>
<Freight>3.35</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-02-12T00:00:00</OrderDate>
<RequiredDate>1998-03-12T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-02-13T00:00:00">
<ShipVia>2</ShipVia>
<Freight>90.97</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
</Orders>
</Root>
您的 JAXB 为客户生成的 class 在注释 @XmlType
的参数 name
下被命名为 CustomerType
,但是在 xml提供简单命名的单个客户标签 Customer
.
将 java class 中的任何声明从 CustomerType
更改为 Customer
编辑:
通过阅读XSD文件,我发现它与XML文件的有效内容不一致:所以我想知道是否还有其他问题?
编辑 2:
正如您在评论中所述,您可以在上述更改后正确解编 xml 文件,但无法检索 for-each 循环中的数据:这是因为一个非常简单的不同问题:您正在迭代 cust
,它被指定为 Customers
的一个全新实例,并且与 root
中有效未编组的内容无关。
因此,请通过更改 class 重构主要代码:
Root root = (Root) unmarshaller.unmarshal(file);
CustomerType orderT = new CustomerType();
Customers cust = new Customers();
for (CustomerType cT : cust.getCustomer()) {
System.out.println(cT.getContactName());
}
至:
Root root = (Root) unmarshaller.unmarshal(file);
for (CustomerType cT : root.getCustomers.getCustomer()) {
System.out.println(cT.getContactName());
}
我使用 Jaxb 从 XSD Java classes 生成,我创建了 unmarshall 方法,但每个值 return 为空。请帮忙!
这是我的主Class:
try {
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema xsdSchema = sf.newSchema(new File(%Here is the PATH% \CustomerAndOrders.xsd"));
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema(xsdSchema);
unmarshaller.setEventHandler(new MyValidationEventHandler());
File file = new File("%Here is the PATH% \ XMLTestFile.xml");
System.out.println(file.getName());
Root root = (Root) unmarshaller.unmarshal(file);
CustomerType orderT = new CustomerType();
Customers cust = new Customers();
for (CustomerType cT : cust.getCustomer()) {
System.out.println(cT.getContactName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
static class MyValidationEventHandler implements ValidationEventHandler {
public boolean handleEvent(ValidationEvent event) {
System.out.println("\nEVENT");
System.out.println("SEVERITY: " + event.getSeverity());
System.out.println("MESSAGE: " + event.getMessage());
System.out.println("LINKED EXCEPTION: " + event.getLinkedException());
System.out.println("LOCATOR");
System.out.println(" LINE NUMBER: " + event.getLocator().getLineNumber());
System.out.println(" COLUMN NUMBER: " + event.getLocator().getColumnNumber());
System.out.println(" OFFSET: " + event.getLocator().getOffset());
System.out.println(" OBJECT: " + event.getLocator().getObject());
System.out.println(" NODE: " + event.getLocator().getNode());
System.out.println(" URL: " + event.getLocator().getURL());
return true;
}
}
使用 Jaxb 生成 classes:
package XMLBeans;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"customers",
"orders"
})
@XmlRootElement(name = "Root")
public class Root {
@XmlElement(name = "Customers", required = true)
protected Root.Customers customers;
@XmlElement(name = "Orders", required = true)
protected Root.Orders orders;
/**
* Gets the value of the customers property.
*
* @return
* possible object is
* {@link Root.Customers }
*
*/
public Root.Customers getCustomers() {
return customers;
}
/**
* Sets the value of the customers property.
*
* @param value
* allowed object is
* {@link Root.Customers }
*
*/
public void setCustomers(Root.Customers value) {
this.customers = value;
}
/**
* Gets the value of the orders property.
*
* @return
* possible object is
* {@link Root.Orders }
*
*/
public Root.Orders getOrders() {
return orders;
}
/**
* Sets the value of the orders property.
*
* @param value
* allowed object is
* {@link Root.Orders }
*
*/
public void setOrders(Root.Orders value) {
this.orders = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Customer" type="{}CustomerType" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"customer"
})
public static class Customers {
@XmlElement(name = "Customer")
protected List<CustomerType> customer;
public List<CustomerType> getCustomer() {
if (customer == null) {
customer = new ArrayList<CustomerType>();
}
return this.customer;
}
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Order" type="{}OrderType" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"order"
})
public static class Orders {
@XmlElement(name = "Order")
protected List<OrderType> order;
/**
* Gets the value of the order property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the order property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getOrder().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link OrderType }
*
*
*/
public List<OrderType> getOrder() {
if (order == null) {
order = new ArrayList<OrderType>();
}
return this.order;
}
}
}
客户类型class
package XMLBeans;
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.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CustomerType", propOrder = {
"companyName",
"contactName",
"contactTitle",
"phone",
"fax",
"fullAddress"
})
public class CustomerType {
@XmlElement(name = "CompanyName", required = true)
protected String companyName;
@XmlElement(name = "ContactName", required = true)
protected String contactName;
@XmlElement(name = "ContactTitle", required = true)
protected String contactTitle;
@XmlElement(name = "Phone", required = true)
protected String phone;
@XmlElement(name = "Fax")
protected String fax;
@XmlElement(name = "FullAddress", required = true)
protected AddressType fullAddress;
@XmlAttribute(name = "CustomerID")
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlSchemaType(name = "token")
protected String customerID;
/**
* Gets the value of the companyName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCompanyName() {
return companyName;
}
/**
* Sets the value of the companyName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCompanyName(String value) {
this.companyName = value;
}
/**
* Gets the value of the contactName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getContactName() {
return contactName;
}
/**
* Sets the value of the contactName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setContactName(String value) {
this.contactName = value;
}
/**
* Gets the value of the contactTitle property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getContactTitle() {
return contactTitle;
}
/**
* Sets the value of the contactTitle property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setContactTitle(String value) {
this.contactTitle = value;
}
/**
* Gets the value of the phone property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPhone() {
return phone;
}
/**
* Sets the value of the phone property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPhone(String value) {
this.phone = value;
}
/**
* Gets the value of the fax property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getFax() {
return fax;
}
/**
* Sets the value of the fax property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setFax(String value) {
this.fax = value;
}
/**
* Gets the value of the fullAddress property.
*
* @return
* possible object is
* {@link AddressType }
*
*/
public AddressType getFullAddress() {
return fullAddress;
}
/**
* Sets the value of the fullAddress property.
*
* @param value
* allowed object is
* {@link AddressType }
*
*/
public void setFullAddress(AddressType value) {
this.fullAddress = value;
}
/**
* Gets the value of the customerID property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCustomerID() {
return customerID;
}
/**
* Sets the value of the customerID property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCustomerID(String value) {
this.customerID = value;
}
}
这是我的样本 XML:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
</Customers>
<Orders>
<Order>
<CustomerID>GREAL</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-05-06T00:00:00</OrderDate>
<RequiredDate>1997-05-20T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-05-09T00:00:00">
<ShipVia>2</ShipVia>
<Freight>3.35</Freight>
<ShipName>Great Lakes Food Market</ShipName>
<ShipAddress>2732 Baker Blvd.</ShipAddress>
<ShipCity>Eugene</ShipCity>
<ShipRegion>OR</ShipRegion>
<ShipPostalCode>97403</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-02-12T00:00:00</OrderDate>
<RequiredDate>1998-03-12T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1998-02-13T00:00:00">
<ShipVia>2</ShipVia>
<Freight>90.97</Freight>
<ShipName>Let's Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
</Orders>
</Root>
您的 JAXB 为客户生成的 class 在注释 @XmlType
的参数 name
下被命名为 CustomerType
,但是在 xml提供简单命名的单个客户标签 Customer
.
将 java class 中的任何声明从 CustomerType
更改为 Customer
编辑: 通过阅读XSD文件,我发现它与XML文件的有效内容不一致:所以我想知道是否还有其他问题?
编辑 2:
正如您在评论中所述,您可以在上述更改后正确解编 xml 文件,但无法检索 for-each 循环中的数据:这是因为一个非常简单的不同问题:您正在迭代 cust
,它被指定为 Customers
的一个全新实例,并且与 root
中有效未编组的内容无关。
因此,请通过更改 class 重构主要代码:
Root root = (Root) unmarshaller.unmarshal(file);
CustomerType orderT = new CustomerType();
Customers cust = new Customers();
for (CustomerType cT : cust.getCustomer()) {
System.out.println(cT.getContactName());
}
至:
Root root = (Root) unmarshaller.unmarshal(file);
for (CustomerType cT : root.getCustomers.getCustomer()) {
System.out.println(cT.getContactName());
}