簡體   English   中英

Jaxb:在同一個包中解組帶有多個名稱空間的xml

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM