[英]Jaxb: Unmarshalling xml with multiple namespaces in same package
我是新手在xml中使用命名空間所以我有點困惑,想要一些澄清。 我有一個java服務,我接收帶有許多不同名稱空間的xml文檔,當我使用它時,我覺得我必須做錯了所以我想檢查。 在我的package-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屬性並設置了Passenger的TicketNumber屬性。 但是我不知道為什么我需要在TicketNumber上的XmlElement注釋上添加名稱空間url才能使用它,但我不需要為Train上的Color屬性執行此操作。 如果我從TicketNumber上的XmlElement注釋中刪除namespace屬性,則xml中的值將不會映射到該對象,除非我還從xml請求中刪除了名稱空間前綴。 我覺得因為我已經在XmlRootElement for Passenger上定義了namespace屬性,所以我不應該為類中的每個字段都這樣做,就像我沒有為Train一樣,所以我假設我必須設置錯誤。 有人能指出我正確的方向嗎? 謝謝!
下面是根據您的模型解釋命名空間如何在JAXB(JSR-222)中工作。
JAVA模型
包信息
以下是@XmlSchema
注釋的修改版本。 它包含一些關鍵信息:
namespace
- 將用於限定全局元素的默認命名空間(對應於未指定其他命名空間的@XmlRootElement
和@XmlElementDecl
注釋(以及基於elementFormDefault
值的本地元素)。 elementFormDefault
默認情況下只有全局元素是名稱空間限定的,但是通過將值設置為XmlNsForm.QUALIFIED
所有沒有指定顯式名稱空間的元素都將使用namespace
值進行限定。 xmlns
是JAXB impl應該用於這些命名空間的首選前綴集(盡管它們可能使用其他前綴)。 @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中/輸出
在下面的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>
欲獲得更多信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.