Как добавить атрибут пространства имен к элементу в JAXB при сортировке?

Я работаю с LMS eBay (Large Merchant Services) и постоянно сталкиваюсь с ошибкой:

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>

Разница заключается в атрибуте пространства имен XML в файле 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. Я попытался бросить 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;

person Community    schedule 17.11.2009    source источник
comment
Что именно вы подразумеваете под сгенерированным через JAXB? Не могли бы вы добавить определение вашего класса AddFixedPriceItemRequest?   -  person Mykola Golubyev    schedule 17.11.2009
comment
Я использую сортировку через JAXB для генерации XML. Я не вижу никакого конкретного тега, который добавляет атрибут xmlns в класс BulkDataExchangeRequestsType. Я добавил к вопросу определение класса AddFixedPriceItemRequestType.   -  person Ryan Elkins    schedule 17.11.2009
comment
Почему бы не сгенерировать схему, указанную в WSDL? developer.ebay.com/webservices/bulk-data-exchange/ последний/   -  person Martin OConnor    schedule 17.11.2009
comment
Вы пытались указать пространство имен в качестве значения атрибута в @XmlType, как в моем ответе?   -  person Mykola Golubyev    schedule 17.11.2009
comment
@Martin OConnor Вы имеете в виду службу BulkDataExchange, но рассматриваемый файл направляется в службу FileTransfer. Все классы, которые я использую, генерируются на основе Merchant API, поскольку eBay заявил, что у них нет точной схемы для службы FileTransfer. Я изменил MerchantData.xsd, чтобы создать то, что у меня есть.   -  person Ryan Elkins    schedule 17.11.2009
comment
@Mykola Golubyev - я попробовал аннотацию типа, но, похоже, ничего не сделал (см. Выше, что я добавил).   -  person Ryan Elkins    schedule 17.11.2009
comment
@Mykola Golubyev - я также попытался изменить @XmlElement, где AddFixedPriceItemRequest определен в BulkDataExchangeRequestsType, опять же безрезультатно.   -  person Ryan Elkins    schedule 18.11.2009
comment
Ok. Давай сделаем это. Вы добавите дополнительный код, который вы используете JAXB для генерации xml, и завтра (если он все еще не будет решен) я напишу свою собственную генерацию JAXB (сейчас у меня нет доступа к моей IDE).   -  person Mykola Golubyev    schedule 18.11.2009
comment
Можете ли вы показать класс BulkDataExchangeRequests со свойством AddFixedPriceItemRequestType?   -  person Mykola Golubyev    schedule 18.11.2009
comment
Сделанный. Я добавил это к вопросу как ОБНОВЛЕНИЕ 3. Спасибо.   -  person Ryan Elkins    schedule 18.11.2009
comment
Вы пытались добавить пространство имен в защищенный список @XmlElement(name = AddFixedPriceItemRequest)‹AddFixedPriceItemRequestType› addFixedPriceItemRequest;   -  person Mykola Golubyev    schedule 18.11.2009
comment
Да, я прямо упомянул об этом в маленьком абзаце перед кодом в обновлении 3. Это не имело никакого эффекта.   -  person Ryan Elkins    schedule 18.11.2009


Ответы (3)


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

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

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

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


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

person skaffman    schedule 17.11.2009
comment
Вы правы, в этом нет никакого смысла, однако я проверял это - отправляя точно такой же файл (их служба LMS требует, чтобы вы загрузили файл, который они затем обрабатывают, когда они в основном до него доберутся), кроме этого одно изменение дополнительного xmlns. Без него служба каждый раз возвращает Failed. Когда он есть, такой проблемы нет. Думаю, я надеялся, что есть более простой способ - перетаскивание через DOM кажется очень громоздким, но я чувствую, что любое решение на данный момент будет зверем. - person Ryan Elkins; 18.11.2009
comment
К сожалению, это, вероятно, не сработает, поскольку он довольно динамичен в том, как он создает свой контент. Хорошая мысль, хотя это не так. - person Ryan Elkins; 18.11.2009

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

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

or

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

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

person Mykola Golubyev    schedule 17.11.2009
comment
это не работает, я столкнулся с той же проблемой, что и плакат - person yolob 21; 14.01.2020

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

person Community    schedule 16.02.2011