2009-11-17 2 views
4

Я работаю с СДО eBay в (Большой Merchant Services) и продолжал работать в ошибку:Как добавить атрибут пространства имен в элемент JAXB при сортировке?

org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.

После много проб и ошибок я проследил проблему вниз. Оказывается, это работает:

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

Разница есть атрибут XML-пространства на AddFixedPriceItemRequest. Весь мой XML в настоящее время сортируется через JAXB, и я не уверен, что лучший способ добавить добавление второго атрибута xmlns в другой элемент в моем файле.

Так вот в чем вопрос. Как добавить атрибут xmlns в другой элемент в JAXB?

UPDATE:

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; 
    } 
} 

Добавлено определение класса по запросу.

ОБНОВЛЕНИЕ 2: Под редакцией выше класс как так никакого эффекта:

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

ОБНОВЛЕНИЕ 3: Вот фрагмент из класса BulkDataExchangeRequestsType. Я попытался бросить namespace="urn:ebay:apis:eBLBaseComponents" в @XmlElement для AddFixedPriceItemRequest, но ничего не сделал.

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

UPDATE 4: Вот отвратительный кусок кода, который обновляет XML после сортировочная для меня. В настоящее время я работаю, хотя я не горжусь этим.

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(true); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.newDocument(); 
    marshaller.marshal(request, doc); 
    NodeList nodes = doc.getChildNodes(); 
    nodes = nodes.item(0).getChildNodes(); 
    for(int i = 0; i < nodes.getLength(); i++){ 
     Node node = nodes.item(i); 
     if (!node.getNodeName().equals("Header")){ 
      ((Element)node).setAttribute("xmlns", "urn:ebay:apis:eBLBaseComponents"); 
     } 
    } 

Спасибо за помощь всем.

+0

Что именно вы подразумеваете под «сгенерированным через JAXB»? Не могли бы вы добавить определение вашего класса AddFixedPriceItemRequest –

+0

Я использую маршаллинг через JAXB для генерации XML. Я не вижу конкретного тега, который добавляет атрибут xmlns в класс BulkDataExchangeRequestsType. Я добавил определение класса AddFixedPriceItemRequestType. –

+0

Почему бы не создать схему, указанную в WSDL? http://developer.ebay.com/webservices/bulk-data-exchange/latest/BulkDataExchangeService.wsdl –

ответ

5

Насколько я могу сказать, ваш XML-фрагменты семантически идентичны. Атрибут xmlns в элементе AddFixedPriceItemRequest является избыточным, поскольку он неявно наследует пространство имен его родительского элемента. JAXB это знает, и поэтому не нужно добавлять пространство имен в AddFixedPriceItemRequest - это просто не нужно.

Если сервер ebay работает только в том случае, когда присутствует AddFixedPriceItemRequestxmlns, он разбит и предъявляет требования к вводимым данным, превышающим требования XML и схемы. Если это действительно так (что трудно поверить, но возможно), то использование XML-модели документа XML, такой как JAXB, будет борьбой, поскольку это предполагает, что XML является XML-XML. Низкоуровневые пустяки о том, какие элементы получают объявления xmlns, не подвергаются API, так как это не нужно.

Ничто из этого не помогает. Моим подходом было бы маршалирование модели JAXB на объект DOM (с использованием DOMResult, переданного в Marshaller), а затем посмотреть, можете ли вы выполнить ручную настройку DOM, чтобы заставить xmlns в документ в соответствующих местах. Затем вы можете сериализовать эту DOM для XML и отправить ее.

Вам не обязательно это делать, и я подозреваю, что вы можете что-то делать неправильно; это более вероятно, чем веб-сервис ebay, который разбивается так.


редактировать: вот еще одно предложение, немного менее ужасны, чем решение JAXB к DOM-к-XML. Если ваш запрос XML является разумным статическим по структуре, только с изменением числовых/строковых значений, определите его как шаблон String, затем замените значения во время выполнения и отправьте это. Затем вы можете интерпретировать результаты с помощью JAXB. Я сделал это в навесе с помощью веб-сервисов, требующих очень точных префиксов пространства имен, когда убеждать XML-библиотеки java в соответствие с этим было необоснованно сложно.

+0

Вы правы, это не имеет никакого смысла, однако, я протестировал его - отправив тот же самый файл (их служба LMS требует, чтобы вы загружали файл, который они затем обрабатывали, когда они обходили его в основном), за исключением что одно изменение дополнительного xmlns. Без него служба возвращает «Failed» каждый раз. Когда он там, у него нет этой проблемы. Наверное, я надеялся, что есть более простой способ - перетащить его через DOM кажется очень громоздким, но я чувствую, что любое решение будет зверь в этот момент. –

+0

см. Править для альтернативы – skaffman

+0

К сожалению, это, вероятно, не будет работать, поскольку оно довольно динамично в том, как он создает свой контент. Хорошая мысль, хотя это не так. –

3

Попробуйте использовать класс аннотации

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

или

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

свойства аннотации, если вы хотите, чтобы указать пространство имен только в некоторых определенных случаях

3

Проверьте, нет ли полей в сгенерированном классе без аннотации @XmlElement, и если они присутствуют, они не имеют атрибут пространства имен. Эти два должны присутствовать, чтобы получить префикс пространства имен для каждого элемента вашего маршалированного xml.

Смежные вопросы