6

我正在使用 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 目前都通过 JAXB 进行编组,我不确定将第二个 xmlns 属性添加到文件中的不同元素的最佳方法是什么。

这就是问题所在。如何将 xmlns 属性添加到 JAXB 中的另一个元素?

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课程的一个片段。我尝试将 anamespace="urn:ebay:apis:eBLBaseComponents"放入@XmlElementforAddFixedPriceItemRequest但它没有做任何事情。

@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;
4

3 回答 3

6

据我所知,您的 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 在结构上是合理的静态,只有数字/字符串值发生变化,则将其定义为字符串模板,然后在运行时替换值,然后发送。然后,您可以使用 JAXB 解释结果。我已经在 oast 中使用 web 服务 thyat 完成了这项工作,需要非常精确的命名空间前缀,而说服 java XML 库遵守这一点非常困难。

于 2009-11-17T21:47:12.837 回答
4

尝试使用类注解

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

或者

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

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

于 2009-11-17T19:12:09.773 回答
4

检查生成的类中的字段是否缺少@XmlElement注释,如果存在,它们是否缺少命名空间属性。这两个必须存在才能针对封送 xml 中的每个元素获取名称空间前缀。

于 2011-02-16T00:22:32.190 回答