2012-12-20 45 views
1

我使用XJC生成Java類此XSD:JAXB反編排的XML對象返回空列表

<?xml version="1.0" encoding="UTF-8"?> 
    <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">  
<xs:element name="message"> 
<xs:complexType> 
    <xs:sequence maxOccurs="unbounded" minOccurs="0"> 
    <xs:element name="key"> 
     <xs:complexType> 
     <xs:simpleContent> 
      <xs:extension base="xs:string"> 
      <xs:attribute type="xs:string" name="name" use="optional"/> 
      <xs:attribute type="xs:string" name="type" use="optional"/> 
      </xs:extension> 
     </xs:simpleContent> 
     </xs:complexType> 
    </xs:element> 
    </xs:sequence> 
    <xs:attribute type="xs:string" name="type"/> 
    <xs:attribute type="xs:string" name="routingType"/> 
    <xs:attribute type="xs:string" name="computerName"/> 
    <xs:attribute type="xs:string" name="userName"/> 
    <xs:attribute type="xs:string" name="module"/> 
</xs:complexType> 
</xs:element> 
</xs:schema> 

我的問題是解組下面的XML:

<message type="MSG_TYPE_TEST" routingType="routed" computerName="PRO31218S82-002" userName="SYSTEM" module="myService"> 
    <key name="HANDLER" type="String">CB</key> 
    <key name="STAND" type="String">01</key> 
</message> 

執行解組的Java src如下所示:

Unmarshaller u = JAXBContext.newInstance(Message.class).createUnmarshaller(); 
JAXBElement<Message> jaxbObject = u.unmarshal(source, Message.class); 
Message message = jaxbObject.getValue(); 
System.out.print(message.getKey().size()); // list is empty 

message.geKey()返回一個空的列表,而message.getType(),message.getRoutingType()和其他屬性getter返回期望值。
我做錯了什麼?

生成的(由XJC)消息類看起來是這樣的:

// 
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2012.12.20 at 09:24:38 AM CET 
// 


package generated; 

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.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 
import javax.xml.bind.annotation.XmlValue; 


/** 
* <p>Java class for anonymous complex type. 
* 
* <p>The following schema fragment specifies the expected content contained within this class. 
* 
* <pre> 
* &lt;complexType> 
* &lt;complexContent> 
*  &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> 
*  &lt;sequence maxOccurs="unbounded" minOccurs="0"> 
*   &lt;element name="key"> 
*   &lt;complexType> 
*    &lt;simpleContent> 
*    &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string"> 
*     &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*     &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*    &lt;/extension> 
*    &lt;/simpleContent> 
*   &lt;/complexType> 
*   &lt;/element> 
*  &lt;/sequence> 
*  &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*  &lt;attribute name="routingType" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*  &lt;attribute name="computerName" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*  &lt;attribute name="userName" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*  &lt;attribute name="module" type="{http://www.w3.org/2001/XMLSchema}string" /> 
*  &lt;/restriction> 
* &lt;/complexContent> 
* &lt;/complexType> 
* </pre> 
* 
* 
*/ 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "key" 
}) 
@XmlRootElement(name = "message") 
public class Message { 

    protected List<Message.Key> key; 
    @XmlAttribute 
    protected String type; 
    @XmlAttribute 
    protected String routingType; 
    @XmlAttribute 
    protected String computerName; 
    @XmlAttribute 
    protected String userName; 
    @XmlAttribute 
    protected String module; 

    /** 
    * Gets the value of the key 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 key property. 
    * 
    * <p> 
    * For example, to add a new item, do as follows: 
    * <pre> 
    * getKey().add(newItem); 
    * </pre> 
    * 
    * 
    * <p> 
    * Objects of the following type(s) are allowed in the list 
    * {@link Message.Key } 
    * 
    * 
    */ 
    public List<Message.Key> getKey() { 
     if (key == null) { 
      key = new ArrayList<Message.Key>(); 
     } 
     return this.key; 
    } 

    /** 
    * Gets the value of the type property. 
    * 
    * @return 
    *  possible object is 
    *  {@link String } 
    *  
    */ 
    public String getType() { 
     return type; 
    } 

    /** 
    * Sets the value of the type property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link String } 
    *  
    */ 
    public void setType(String value) { 
     this.type = value; 
    } 

    /** 
    * Gets the value of the routingType property. 
    * 
    * @return 
    *  possible object is 
    *  {@link String } 
    *  
    */ 
    public String getRoutingType() { 
     return routingType; 
    } 

    /** 
    * Sets the value of the routingType property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link String } 
    *  
    */ 
    public void setRoutingType(String value) { 
     this.routingType = value; 
    } 

    /** 
    * Gets the value of the computerName property. 
    * 
    * @return 
    *  possible object is 
    *  {@link String } 
    *  
    */ 
    public String getComputerName() { 
     return computerName; 
    } 

    /** 
    * Sets the value of the computerName property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link String } 
    *  
    */ 
    public void setComputerName(String value) { 
     this.computerName = value; 
    } 

    /** 
    * Gets the value of the userName property. 
    * 
    * @return 
    *  possible object is 
    *  {@link String } 
    *  
    */ 
    public String getUserName() { 
     return userName; 
    } 

    /** 
    * Sets the value of the userName property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link String } 
    *  
    */ 
    public void setUserName(String value) { 
     this.userName = value; 
    } 

    /** 
    * Gets the value of the module property. 
    * 
    * @return 
    *  possible object is 
    *  {@link String } 
    *  
    */ 
    public String getModule() { 
     return module; 
    } 

    /** 
    * Sets the value of the module property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link String } 
    *  
    */ 
    public void setModule(String value) { 
     this.module = value; 
    } 


    /** 
    * <p>Java class for anonymous complex type. 
    * 
    * <p>The following schema fragment specifies the expected content contained within this class. 
    * 
    * <pre> 
    * &lt;complexType> 
    * &lt;simpleContent> 
    *  &lt;extension base="&lt;http://www.w3.org/2001/XMLSchema>string"> 
    *  &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" /> 
    *  &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" /> 
    *  &lt;/extension> 
    * &lt;/simpleContent> 
    * &lt;/complexType> 
    * </pre> 
    * 
    * 
    */ 
    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "", propOrder = { 
     "value" 
    }) 
    public static class Key { 

     @XmlValue 
     protected String value; 
     @XmlAttribute 
     protected String name; 
     @XmlAttribute 
     protected String type; 

     /** 
     * Gets the value of the value property. 
     * 
     * @return 
     *  possible object is 
     *  {@link String } 
     *  
     */ 
     public String getValue() { 
      return value; 
     } 

     /** 
     * Sets the value of the value property. 
     * 
     * @param value 
     *  allowed object is 
     *  {@link String } 
     *  
     */ 
     public void setValue(String value) { 
      this.value = value; 
     } 

     /** 
     * Gets the value of the name property. 
     * 
     * @return 
     *  possible object is 
     *  {@link String } 
     *  
     */ 
     public String getName() { 
      return name; 
     } 

     /** 
     * Sets the value of the name property. 
     * 
     * @param value 
     *  allowed object is 
     *  {@link String } 
     *  
     */ 
     public void setName(String value) { 
      this.name = value; 
     } 

     /** 
     * Gets the value of the type property. 
     * 
     * @return 
     *  possible object is 
     *  {@link String } 
     *  
     */ 
     public String getType() { 
      return type; 
     } 

     /** 
     * Sets the value of the type property. 
     * 
     * @param value 
     *  allowed object is 
     *  {@link String } 
     *  
     */ 
     public void setType(String value) { 
      this.type = value; 
     } 

    } 

} 

回答

1

根據你在你的問題貼,運行以下的Message類:

package generated; 

import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     StreamSource source = new StreamSource("src/generated/input.xml"); 

     Unmarshaller u = JAXBContext.newInstance(Message.class).createUnmarshaller(); 
     JAXBElement<Message> jaxbObject = u.unmarshal(source, Message.class); 
     Message message = jaxbObject.getValue(); 
     System.out.print(message.getKey().size()); // list is empty 
    } 

} 

我得到以下輸出,顯示正確填充的集合:

2 

我也得到正確的輸出,當我產生從您發佈的XML模式的新模式,我改變了我創建的JAXBContext以下方式:

Unmarshaller u = JAXBContext.newInstance("generated").createUnmarshaller(); 

UPDATE

我的XSD其實也有一個目標名稱(我沒有張貼)和 從xsd中刪除這個時,我得到你得到的結果。你有 暗示如何解決這個問題?

如果您schema元素看起來像下面這樣:

<xs:schema 
    elementFormDefault="qualified" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.com/foo"> 

那麼你的XML文檔必須聲明,命名空間和相應資格的元素。它可能看起來像:

<message 
    xmlns="http://www.example.com/foo" 
    type="MSG_TYPE_TEST" 
    routingType="routed" 
    computerName="PRO31218S82-002" 
    userName="SYSTEM" module="myService"> 
    <key name="HANDLER" type="String">CB</key> 
    <key name="STAND" type="String">01</key> 
</message> 

然後因爲你從XML模式生成的模型,我建議創建JAXBContext上生成的包名。這將確保從package-info類的@XmlSchema註釋中提取模式元數據。

Unmarshaller u = JAXBContext.newInstance("generated").createUnmarshaller(); 
+1

非常感謝您的快速響應和幫助。我的xsd實際上也有一個targetnamespace(我沒有發佈),當從xsd中刪除它時,我得到了你得到的結果。你有關於如何解決這個問題的提示嗎? – user1918098

+0

@ user1918098 - 我根據您的評論更新了我的答案。 –

+1

輝煌。再次感謝 – user1918098