私は、単一の Java クラスにマッピングしている無意味なラッパーがたくさんある深い XML 構造を持っています。単純なデータ型を @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>
ルート.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;
}
}
マーシャラー/アンマーシャラー
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!");
}
}
パッケージ情報.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)Path に関係があると推測しています。
package-info.java
また、これらのオブジェクトを操作するときに使用しているマーシャラー/アンマーシャラーも追加しました。jaxb.properties には刺激的なものが何も含まれていないため、省略しました。