我使用Jaxb从XSD生成Java类,创建了unmarshall方法,但是每个值都返回null。请帮忙!
这是我的主要课程:
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生成的类:
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;
}
}
}
CustomerType类
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>
答案 0 :(得分:1)
您在注释CustomerType
的参数name
的参数@XmlType
下为您的JAXB生成的客户类命名为Customer
,但是在您提供的xml上,简单地命名了{{ 1}}。
将Java类中的任何声明从CustomerType
更改为Customer
编辑: 通过阅读XSD文件,我发现它与XML文件的有效内容不一致:因此,我想知道是否还会有其他问题?
编辑2:
如您在注释中所述,您可以在上述更改之后正确地取消xml文件的编组,但是无法在for-each循环中检索数据:这是由于另一个非常简单的问题:您正在遍历cust
被分配为Customers
的全新实例,并且与内容无关,实际上未在root
内部编组。
因此,请通过更改以下内容来重构主类的代码:
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());
}