在编组时如何向JAXB中的元素添加命名空间属性?

Rya*_*ins 4 java xml jaxb xml-namespaces

我正在使用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">
Run Code Online (Sandbox Code Playgroud)

虽然这(我发送的内容)不是:

<?xml version="1.0" encoding="UTF-8"?>
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents">
  <Header>
    <Version>583</Version>
    <SiteID>0</SiteID>
  </Header>
  <AddFixedPriceItemRequest>
Run Code Online (Sandbox Code Playgroud)

区别在于xml命名空间属性AddFixedPriceItemRequest.我的所有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;
    }
}
Run Code Online (Sandbox Code Playgroud)

根据请求添加了类定义.

更新2:编辑上面的类似乎没有效果:

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

更新3:这是BulkDataExchangeRequestsType类的片段.我尝试BulkDataExchangeRequestsType在AddFixedPriceItemRequest的@XmlElement中抛出一个,但它没有做任何事情.

@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;
Run Code Online (Sandbox Code Playgroud)

更新4:这是在为我编组后更新xml的可怕代码块.这项工作目前正在进行中,尽管我并不为此感到自豪.

<?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">
Run Code Online (Sandbox Code Playgroud)

谢谢各位的帮助.

Myk*_*yev 5

尝试使用类注释

@XmlType(namespace="urn:ebay:apis:eBLBaseComponents")
Run Code Online (Sandbox Code Playgroud)

或者

@XmlElement(namespace="urn:ebay:apis:eBLBaseComponents")
Run Code Online (Sandbox Code Playgroud)

如果您只想在某些特定情况下指定名称空间,则可以使用属性注释


ska*_*man 5

据我所知,您的XML片段在语义上是相同的.在xmlns该属性上的AddFixedPriceItemRequest元件是多余的,因为它暗示继承父元素的命名空间.JAXB知道这一点,所以不打扰添加命名空间AddFixedPriceItemRequest- 它只是没有必要.

如果ebay服务器仅在AddFixedPriceItemRequest xmlns存在时工作,那么它就会被破坏,并且对输入的要求超出了XML和模式所要求的那些.如果情况确实如此(很难相信,但可能),那么使用像JAXB这样的Java XML文档模型将会很困难,因为这将假设XML是XML就是XML.关于哪些元素获得xmlns声明的低级放弃不会暴露给API,因为它不应该被需要.

这些都没有帮助你.我的方法是将JAXB模型封送到DOM对象(使用DOMResult传递给Marshaller),然后看看是否可以对DOM进行一些手动调整以强制xmlns进入适当位置的文档.然后,您可以将该DOM序列化为XML并发送它.

你不应该这样做,我怀疑你可能在某处做了别的错事; 这比ebay网络服务更容易被破坏.


编辑:这是另一个建议,比JAXB-to-DOM-to-XML解决方案更糟糕.如果您的请求XML在结构上是合理的静态,只更改了numeric/string值,那么将其定义为String模板,然后在运行时替换值,并发送它.然后,您可以使用JAXB解释结果.我已经在使用web服务的oast中完成了这项工作,因为在说服java XML库符合这一点时,必须使用非常精确的名称空间前缀.