繁体   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