我遇到了JAXB和Unmarshalling以下XML的问题
<ns2:ID entry-method="manual"> 123456789012345678
<ns2:ID2>123456789012345678</ns2:ID2>
</ns2:ID>
我获得了模式并使用JAXB xjc工具生成了以下属性定义:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"ID1",
"ID2",
"ID3"
})
@XmlRootElement(name = "ID")
public class ID {
@XmlElement(name = "ID1")
protected String id1;
@XmlElement(name = "ID2")
protected String id2;
@XmlElement(name = "ID3")
protected String id3;
@XmlAttribute(name = "entryMethod")
protected String entryMethod;
public String getId1() {
return id1
}
public void setId1(String value) {
this.id1 = value;
}
public String getId2() {
return id2
}
public void setId2(String value) {
this.id2 = value;
}
public String getId3() {
return id3;
}
public void setId3(String value) {
this.id3 = value;
}
public String getEntryMethod() {
if (entryMethod == null) {
return "swipe";
} else {
return entryMethod;
}
}
public void setEntryMethod(String value) {
this.entryMethod = value;
}
}
正如您所看到的,发送XML的设备不包含ID1标记,它只是将ID1数据添加为根标记的值。当解组此Xml时,对getID1的任何调用都返回null。我很困惑用什么注释来改变类以支持根标记中的数据分配给id1字段。
关于注释更改的任何想法都会使这项工作成功吗?
答案 0 :(得分:2)
您的ID类应该是......
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"content"
})
@XmlRootElement(name = "ID")
public class ID {
@XmlElementRefs({
@XmlElementRef(name = "ID3", type = JAXBElement.class),
@XmlElementRef(name = "ID2", type = JAXBElement.class),
@XmlElementRef(name = "ID1", type = JAXBElement.class)
})
@XmlMixed
protected List<Serializable> content;
@XmlAttribute(name = "entry-method")
protected String entryMethod;
/**
* Gets the value of the content 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 content property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getContent().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link String }
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
* {@link JAXBElement }{@code <}{@link String }{@code >}
*
*
*/
public List<Serializable> getContent() {
if (content == null) {
content = new ArrayList<Serializable>();
}
return this.content;
}
/**
* Gets the value of the entryMethod property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getEntryMethod() {
return entryMethod;
}
/**
* Sets the value of the entryMethod property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setEntryMethod(String value) {
this.entryMethod = value;
}
}
我用这个主要的方法尝试了这个bean ...
public static void main(String[] args) throws JAXBException {
final JAXBContext context = JAXBContext.newInstance(ID.class);
final Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final ID id = new ID();
id.setEntryMethod("method");
ObjectFactory o = new ObjectFactory();
id.getContent().add("sample text");
id.getContent().add(o.createIDID1("id1"));
m.marshal(id, System.out);
}
输出生成为..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ID entry-method="method">sample text
<ID1>id1</ID1>
</ID>
我希望我已经向你提供了有关你问题的所有答案。
答案 1 :(得分:2)
您正在解组的XML与您从中生成对象模型的XML架构不匹配。
<ns2:ID entry-method="manual"> 123456789012345678
<ns2:ID2>123456789012345678</ns2:ID2>
</ns2:ID>
当元素同时具有文本和元素时,据说它具有混合内容。您的XML架构目前不会考虑到这一点。
将与ID
元素对应的复杂类型的定义更改为mixed="true"
。然后重新生成JAXB模型。
由于混合内容的类型分散在子元素中,因此您将获得一个非常不同的JAXB模型。基本上ID
的类将包含一个包含所有内容的List
属性。这对于找到XML格式是必要的。
答案 2 :(得分:2)
这是XML的正确XML架构内容(省略命名空间):
<xs:element name="ID" type="IdType"/>
<xs:complexType name="IdType" mixed="true">
<xs:sequence>
<xs:element name="id2" type="xs:string"/>
<xs:element name="id3" type="xs:string"/>
</xs:sequence>
<xs:attribute name="entry-method" type="xs:string"/>
</xs:complexType>
令人遗憾的结果是生成的类IdType包含
public List<Serializable> getContent() {
if (content == null) {
content = new ArrayList<Serializable>();
}
return this.content;
}
用于包含ID文本子(children!)和所有ID元素子项。因此,ID的处理可能类似于:
JAXBElement<IdType> jbe =
(JAXBElement<IdType>)u.unmarshal( new File( "mixed.xml" ) );
for( Object obj: jbe.getValue().getContent() ){
System.out.println( obj.getClass() + " " + obj );
if( obj instanceof String ){
// text child (even the blank space
} else if( obj instanceof JAXBElement ){
// process an element child wrapped into JAXBElement
}
}