簡體   English   中英

在編組時如何向JAXB中的元素添加命名空間屬性?

[英]How do I add a namespace attribute to an element in JAXB when marshalling?

我正在使用eBay的LMS(大型商戶服務),並一直遇到錯誤:

org.xml.sax.SAXException:
SimpleDeserializer遇到了一個孩子
元素,這是不期望的,在
它試圖嘗試的東西
反序列化。

經過大量的反復試驗,我追查了問題。 事實證明這是有效的:

<?xml version="1.0" encoding="UTF-8"?>
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents">
  <Header>
    <Version>583</Version>
    <SiteID>0</SiteID>
  </Header>
  <AddFixedPriceItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">

雖然這(我發送的內容)沒有:

<?xml version="1.0" encoding="UTF-8"?>
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents">
  <Header>
    <Version>583</Version>
    <SiteID>0</SiteID>
  </Header>
  <AddFixedPriceItemRequest>

區別在於AddFixedPriceItemRequest上的XML名稱空間屬性。 我的所有XML目前都是通過JAXB進行編組的,我不確定將第二個xmlns屬性添加到文件中的其他元素的最佳方法是什么。

這就是問題所在。 如何在JAXB中將xmlns屬性添加到另一個元素?

package ebay.apis.eblbasecomponents;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AddFixedPriceItemRequestType", propOrder = {
    "item"
})
public class AddFixedPriceItemRequestType
    extends AbstractRequestType
{

    @XmlElement(name = "Item")
    protected ItemType item;

    public ItemType getItem() {
        return item;
    }

    public void setItem(ItemType value) {
        this.item = value;
    }
}

根據請求添加了類定義。

像這樣編輯上面的類沒有效果:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "urn:ebay:apis:eBLBaseComponents",
name = "AddFixedPriceItemRequestType", propOrder = {
    "item"
})
public class AddFixedPriceItemRequestType

這是BulkDataExchangeRequestsType類的片段。 我試着扔namespace="urn:ebay:apis:eBLBaseComponents"@XmlElementAddFixedPriceItemRequest但它沒有做任何事情。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BulkDataExchangeRequestsType", propOrder = {
    "header",
    "addFixedPriceItemRequest"
})
public class BulkDataExchangeRequestsType {

    @XmlElement(name = "Header")
    protected MerchantDataRequestHeaderType header;
    @XmlElement(name = "AddFixedPriceItemRequest")
    protected List<AddFixedPriceItemRequestType> addFixedPriceItemRequest;

據我所知,您的XML片段在語義上是相同的。 AddFixedPriceItemRequest元素上的xmlns屬性是多余的,因為它隱式繼承其父元素的命名空間。 JAXB知道這一點,因此不打算將命名空間添加到AddFixedPriceItemRequest - 它只是沒有必要。

如果ebay服務器僅在存在AddFixedPriceItemRequest xmlns時才起作用,那么它就會被破壞,並且對輸入的要求超出了XML和模式所要求的那些。 如果情況確實如此(很難相信,但可能),那么使用像JAXB這樣的Java XML文檔模型將會很困難,因為這將假設XML是XML就是XML。 關於哪些元素獲取xmlns聲明的低級放棄不會暴露給API,因為它不應該被需要。

這些都沒有幫助你。 我的方法是將JAXB模型編組到DOM對象(使用傳遞給MarshallerDOMResult ),然后查看是否可以對DOM進行一些手動調整以強制xmlns進入適當位置的文檔。 然后,您可以將該DOM序列化為XML並發送它。

你不應該這樣做,我懷疑你可能在某處做了別的錯事; 這比ebay網絡服務更容易被破壞。


編輯:這是另一個建議,比JAXB-to-DOM-to-XML解決方案更糟糕。 如果您的請求XML在結構上是合理的靜態,只更改了數字/字符串值,則將其定義為String模板,然后在運行時替換值,並發送它。 然后,您可以使用JAXB解釋結果。 我已經在使用web服務的oast中完成了這項工作,因為在說服java XML庫符合這一點時,必須使用非常精確的名稱空間前綴。

嘗試使用類注釋

@XmlType(namespace="urn:ebay:apis:eBLBaseComponents")

要么

@XmlElement(namespace="urn:ebay:apis:eBLBaseComponents")

如果您只想在某些特定情況下指定命名空間,請使用屬性注釋

檢查生成的類中的字段是否缺少@XmlElement注釋,如果存在則缺少命名空間屬性。 必須存在這兩個,以便為封送的xml中的每個元素獲取名稱空間前綴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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