简体   繁体   English

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

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

I'm working with eBay's LMS (Large Merchant Services) and kept running into the error: 我正在使用eBay的LMS(大型商户服务),并一直遇到错误:

org.xml.sax.SAXException: org.xml.sax.SAXException:
SimpleDeserializer encountered a child SimpleDeserializer遇到了一个孩子
element, which is NOT expected, in 元素,这是不期望的,在
something it was trying to 它试图尝试的东西
deserialize. 反序列化。

After a lot of trial and error I traced the problem down. 经过大量的反复试验,我追查了问题。 It turns out this works: 事实证明这是有效的:

<?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">

While this (what I've been sending) doesn't: 虽然这(我发送的内容)没有:

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

The difference is the XML namespace attribute on the AddFixedPriceItemRequest . 区别在于AddFixedPriceItemRequest上的XML名称空间属性。 All of my XML is currently being marshalled via JAXB and I'm not sure what is the best way to go about adding a second xmlns attribute to a different element in my file. 我的所有XML目前都是通过JAXB进行编组的,我不确定将第二个xmlns属性添加到文件中的其他元素的最佳方法是什么。

So that's the question. 这就是问题所在。 How do I add an xmlns attribute to another element in JAXB? 如何在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;
    }
}

Added class definition by request. 根据请求添加了类定义。

Edited the above class like so to no effect: 像这样编辑上面的类没有效果:

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

Here is a snippet of the BulkDataExchangeRequestsType class. 这是BulkDataExchangeRequestsType类的片段。 I tried throwing a namespace="urn:ebay:apis:eBLBaseComponents" into the @XmlElement for AddFixedPriceItemRequest but it didn't do anything. 我试着扔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;

As far as I can tell, your XML fragments are semantically identical. 据我所知,您的XML片段在语义上是相同的。 The xmlns attribute on the AddFixedPriceItemRequest element is redundant, since it implicitly inherits the namespace of its parent element. AddFixedPriceItemRequest元素上的xmlns属性是多余的,因为它隐式继承其父元素的命名空间。 JAXB knows this, and so doesn't bother adding the namespace to AddFixedPriceItemRequest - it's just not necessary. JAXB知道这一点,因此不打算将命名空间添加到AddFixedPriceItemRequest - 它只是没有必要。

If the ebay server is only working when the AddFixedPriceItemRequest xmlns is present, then it's broken, and is making demands on the input over and above those required by XML and by the schema. 如果ebay服务器仅在存在AddFixedPriceItemRequest xmlns时才起作用,那么它就会被破坏,并且对输入的要求超出了XML和模式所要求的那些。 If this is indeed the case (which is hard to believe, but possible), then using a Java XML document model like JAXB is going to be a struggle, since that will assume XML is XML is XML. 如果情况确实如此(很难相信,但可能),那么使用像JAXB这样的Java XML文档模型将会很困难,因为这将假设XML是XML就是XML。 Low-level farting about with which elements get the xmlns declarations is not exposed to the API, since it shouldn't be needed. 关于哪些元素获取xmlns声明的低级放弃不会暴露给API,因为它不应该被需要。

None of which is helping you. 这些都没有帮助你。 My approach would be to marshal the JAXB model to a DOM object (using a DOMResult passed to the Marshaller ), and then see if you can do some manual tweaking of the DOM to force the xmlns into the document at the appropriate places. 我的方法是将JAXB模型编组到DOM对象(使用传递给MarshallerDOMResult ),然后查看是否可以对DOM进行一些手动调整以强制xmlns进入适当位置的文档。 You can then serialize that DOM to XML and send that. 然后,您可以将该DOM序列化为XML并发送它。

You shouldn't have to do this, and I suspect you may be doing something else wrong somewhere; 你不应该这样做,我怀疑你可能在某处做了别的错事; this is more likely than the ebay web service being broken like this. 这比ebay网络服务更容易被破坏。


edit: here's another suggestion, a bit less awful than the JAXB-to-DOM-to-XML solution. 编辑:这是另一个建议,比JAXB-to-DOM-to-XML解决方案更糟糕。 If your request XML is reasonable static in structure, with only the numeric/string values changing, then define it as a String template, then replace the values at runtime, and send that. 如果您的请求XML在结构上是合理的静态,只更改了数字/字符串值,则将其定义为String模板,然后在运行时替换值,并发送它。 You can then interpret the results using JAXB. 然后,您可以使用JAXB解释结果。 I've done this in the oast with web services thyat required very exact namespace prefixes, when persuading the java XML libraries to conform to that was unreasonably hard. 我已经在使用web服务的oast中完成了这项工作,因为在说服java XML库符合这一点时,必须使用非常精确的名称空间前缀。

Try to use class annotation 尝试使用类注释

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

or 要么

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

property annotation if you only want to specify namespace only in some certain cases 如果您只想在某些特定情况下指定命名空间,请使用属性注释

Check if the fields in a generated classed are missing the @XmlElement annotation and if present are they missing the namespace attribute. 检查生成的类中的字段是否缺少@XmlElement注释,如果存在则缺少命名空间属性。 These two must be present in order to get the namespace prefix against every element in your marshaled xml. 必须存在这两个,以便为封送的xml中的每个元素获取名称空间前缀。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM