我有一個很深的XML結構,其中包含很多無意義的包裝,我將其映射到單個Java類。使用@XmlPath映射簡單的數據類型是在公園散步,但是當涉及到實際需要他們自己的類的類型時,我不太清楚該怎麼做,特別是當這些類型應該放在列表中時。使用帶jaxb/MOXy的@XmlPath映射覆雜類型
我有問題將以下示例中的所有element
類型映射到我的Element
類。由於elements
包裝駐留在使用@XmlPath
映射的資源中,因此我無法使用@XmlElementWrapper
,否則這將是我通常會這樣做的方式。
實施例的XML結構
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:root xsi:schemaLocation="http://www.example.eu/test ResourceSchema.xsd" xmlns:s="http://www.example.eu/test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:resource>
<s:information>
<s:date>2013-07-04</s:date>
<s:name>This example does not work</s:name>
</s:information>
<s:elements>
<s:refobj>
<s:id>1</s:id>
<s:source>First Source</s:source>
</s:refobj>
<s:refobj>
<s:id>2</s:id>
<s:source>Second Source</s:source>
</s:refobj>
<s:refobj>
<s:id>5</s:id>
<s:source>Fifth Source</s:source>
</s:refobj>
</s:elements>
</s:resource>
</s:root>
Root.java
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlPath("resource/information/date/text()")
private String date;
@XmlPath("s:resource/s:information/s:name/text()")
private String name;
@XmlPath("resource/elements/refobj")
private List<RefObj> refObjs;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
RefObj.java
@XmlRootElement(name = "refobj")
@XmlAccessorType(XmlAccessType.FIELD)
public class RefObj {
@XmlElement(name = "id")
private int id;
@XmlElement(name = "source")
private String source;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
}
的Marshaller/Unmarshaller的
public static void main(String[] args) {
String xml = getXML();
Root root = null;
try {
JAXBContext context = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader stringReader = new StringReader(xml);
root = (Root) unmarshaller.unmarshal(stringReader);
} catch (Exception ex) {
System.err.println("Failed to unmarshal XML!");
}
try {
JAXBContext context = JAXBContext.newInstance(Root.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.eu/test ResourceSchema.xsd");
StringWriter stringWriter = new StringWriter();
marshaller.marshal(root, stringWriter);
System.out.println(new String(stringWriter.toString().getBytes(Charset.forName("UTF-8"))));
} catch (Exception ex) {
System.err.println("Failed to marshal object!");
}
}
package-info.java
@XmlSchema(
namespace = "http://www.example.eu/test",
attributeFormDefault = XmlNsForm.QUALIFIED,
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns = {
@XmlNs(
prefix = "s",
namespaceURI = "http://www.example.eu/test")
},
location = "http://www.example.eu/test ResourceSchema.xsd")
package se.example.mavenproject1;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
我可以執行應用程序,但是當我解組/編組的XML內容沒有元素被映射,而不是我得到一個僅包含信息的XML表示。
更新
張貼前面的例子中,我意識到,它實際工作按計劃,這讓我更糊塗了。雖然我試圖在我的生產代碼中複製(以前的)工作示例但沒有取得任何成功,儘管我已經設法實際將我遇到的問題引入示例代碼中。因爲我需要爲出現的問題添加命名空間,所以我假設它與命名約定和X(ml)路徑有關。
我也添加了package-info.java
和我在使用這些對象時使用的編組器/解組器。由於jaxb.properties不包含任何令人興奮的東西,所以我將它遺漏了。
感謝您的迴應,當我實際上爲示例代碼創建項目時,我寫的代碼也適用於我。現在我已經設法通過向xml添加名稱空間來重新創建問題,我還對示例中類的命名做了一些更改,以便更好地類似實際(巨大)xml中的命名圖書館內有任何魔法多元化。 –
@JakobPogulis - 我更新了地址名稱空間限定的答案。 –