私はxmlで名前空間を使用するのが初めてなので、混乱しているので、説明を求めます。 Javaサービスがあり、多くの異なる名前空間を持つxmlドキュメントを受信しています。それを機能させている間、何か間違ったことをしたのでチェックしたいと思います。私のパッケージでは- info.Java次のようなスキーマ注釈があります。
@javax.xml.bind.annotation.XmlSchema(
xmlns={
@javax.xml.bind.annotation.XmHS(prefix="train", namespaceURI="http://mycompany/train"),
@javax.xml.bind.annotation.XmHS(prefix="passenger", namespaceURI="http://mycompany/passenger")
},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm=QUALIFIED
)
クラスレベルで次のように注釈を付けたTrain.Javaがあります。
@XmlRootElement(name="Train", namespace="http://mycompany/train")
そして、注釈が付けられたクラスの各フィールド:
@XmlElement(name="Color") for example
電車には乗客のリストが含まれているため、プロパティがあります
private Set<Passenger> passengers;
このコレクションには次の注釈が付けられています。
@XmlElementWrapper(name="Passengers")
@XmlElements(@XmlElement(name="Passenger", namespace="http://mycompany/passenger"))
次に、Passenger.Java内で、クラス自体に次の注釈が付けられます。
@XmlElement(name="Passenger", namespace="http://mycompany/passenger")
最後に、Passenger.Java内の個々のフィールドについて、次のように注釈が付けられます。
@XmlElement(name="TicketNumber", namespace="http://mycompany/passenger")
したがって、次のようなxmlがある場合:
<train:Train>
<train:Color>Red</train:Color>
<train:Passengers>
<train:Passenger>
<passenger:TicketNumber>T101</passenger:TicketNumber>
</train:Passenger>
</train:Passengers>
</train:Train>
次に、受け取ったこのxmlを非整列化し、TrainのColorプロパティが設定され、乗客のTicketNumberプロパティが設定されます。しかし、なぜそれが機能するようにTicketNumberのXmlElementアノテーションに名前空間URLを追加する必要があるのかはわかりませんが、TrainのColorプロパティに対してはそうする必要はありませんでした。 TicketNumberのXmlElementアノテーションから名前空間属性を削除すると、xmlリクエストから名前空間プレフィックスも削除しない限り、xmlの値がオブジェクトにマッピングされません。 PassengerのXmlRootElementで定義されている名前空間属性を持っているので、クラスのすべてのフィールドに対してこれを行う必要はないはずです。設定が間違っている必要があります。誰かが私を正しい方向に向けることができますか?ありがとう!
以下は、モデルに基づいて JAXB(JSR-222) で名前空間がどのように機能するかを説明したものです。
Javaモデル
package-info
以下は、@XmlSchema
アノテーションの変更バージョンです。いくつかの重要な情報が含まれています。
namespace
-別の名前空間が指定されていないグローバル要素(@XmlRootElement
および@XmlElementDecl
アノテーション(およびelementFormDefault
値に基づくローカル要素)に対応するもの)を修飾するために使用されるデフォルトの名前空間。elementFormDefault
デフォルトではグローバル要素のみが名前空間修飾されますが、値をXmlNsForm.QUALIFIED
に設定すると、明示的な名前空間が指定されていないすべての要素がnamespace
値で修飾されます。xmlns
は、JAXB実装がこれらの名前空間に使用する必要があるプレフィックスの推奨セットです(ただし、他のプレフィックスを使用する場合があります)。@XmlSchema(
namespace="http://mycompany/train",
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns={
@XmlNs(prefix="train", namespaceURI="http://mycompany/train"),
@XmlNs(prefix="passenger", namespaceURI="http://mycompany/passenger")
}
)
package forum15772478;
import javax.xml.bind.annotation.*;
電車
Train
クラスに対応するすべての要素は、@XmlSchema
アノテーションで指定されたnamespace
に対応するため、名前空間情報を指定する必要はありません。
@XmlRootElement
アノテーションはグローバル要素に対応します。@XmlElementWrapper
および@XmlElement
アノテーションはローカル要素に対応します。package forum15772478;
import Java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="Train")
public class Train {
private List<Passenger> passengers;
@XmlElementWrapper(name="Passengers")
@XmlElement(name="Passenger")
public List<Passenger> getPassengers() {
return passengers;
}
public void setPassengers(List<Passenger> passengers) {
this.passengers = passengers;
}
}
乗客
Passenger
クラスのプロパティに対応するすべての要素がhttp://mycompany/passenger
名前空間にある場合、@XmlType
アノテーションを使用して@XmlSchema
アノテーションからnamespace
をオーバーライドできます。
package forum15772478;
import javax.xml.bind.annotation.*;
@XmlType(namespace="http://mycompany/passenger")
public class Passenger {
private String ticketNumber;
@XmlElement(name="TicketNumber")
public String getTicketNumber() {
return ticketNumber;
}
public void setTicketNumber(String ticketNumber) {
this.ticketNumber = ticketNumber;
}
}
または、プロパティレベルで名前空間をオーバーライドできます。
package forum15772478;
import javax.xml.bind.annotation.*;
public class Passenger {
private String ticketNumber;
@XmlElement(
namespace="http://mycompany/passenger",
name="TicketNumber")
public String getTicketNumber() {
return ticketNumber;
}
public void setTicketNumber(String ticketNumber) {
this.ticketNumber = ticketNumber;
}
}
デモコード
次のデモコードを実行して、すべてが機能することを証明できます。
デモ
package forum15772478;
import Java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Train.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum15772478/input.xml");
Train train = (Train) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(train, System.out);
}
}
input.xml/Output
以下のXMLに、質問のXMLドキュメントから欠落していた必要な名前空間宣言を追加しました。
<train:Train
xmlns:train="http://mycompany/train"
xmlns:passenger="http://mycompany/passenger">
<train:Color>Red</train:Color>
<train:Passengers>
<train:Passenger>
<passenger:TicketNumber>T101</passenger:TicketNumber>
</train:Passenger>
</train:Passengers>
</train:Train>
詳細情報