Java-объект для XML-элементов? - PullRequest
4 голосов
/ 04 мая 2010

Я работаю над клиентским приложением веб-сервисов, и оно у меня в основном работает. Я могу получать и читать данные со стороннего веб-сервиса нормально. Теперь мне нужно предоставить некоторые данные, и я застрял.

Классы для объектов, которые я извлекаю / отправляю, были сгенерированы из файлов XSD с помощью инструмента xjc. Часть, на которой я застрял, превращает один из этих объектов в дерево XML для отправки в веб-сервис.

Когда я получаю / отправляю запрос от / к ws, он содержит объект «полезной нагрузки». Это определено в Java-коде как (частичный листинг):

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PayloadType", propOrder = {
    "compressed",
    "document",
    "any",
    "format"
})
public class PayloadType {

    @XmlElement(name = "Compressed")
    protected String compressed;
    @XmlElement(name = "Document")
    protected List<String> document;
    @XmlAnyElement
    protected List<Element> any;
    protected String format;

    public List<Element> getAny() {
        if (any == null) {
            any = new ArrayList<Element>();
        }
        return this.any;
    }

}

Единственное поле, которое меня интересует, это поле any, которое содержит дерево XML. Когда я получаю данные из ws, я читаю это поле примерно так: ('root' имеет тип org.w3c.dom.Element и является результатом вызова getAny (). get (0) 'для объекта полезной нагрузки)

NodeList nl = root.getElementsByTagName("ns1:Process"); // "ns1:Process" is an XML node to do something with
if (nl != null && nl.getLength() > 0) {
    for (int i = 0; i < nl.getLength(); i++) {
        Element proc = (Element) nl.item(i);
        try {
            // do something with the 'proc' Element here...
        } catch (Exception ex) {
            // handle problems here...
        }
    }
}

Отправка данных - вот где я застрял. Как мне взять объект Java, созданный из одного из классов, созданных из XSD, и превратить его в объект Element, который я могу добавить в «любой» список объекта полезной нагрузки? Например, если у меня есть класс DailyData, и я создаю и заполняю его данными:

DailyData dData = new DailyData();
dData.setID = 34;
dData.setValues = "3,5,76,23";

Как добавить этот объект «dData» в «любой» список объекта полезной нагрузки? Это должен быть Элемент. Я делаю что-то с маршаллером JAXBContext? Я использовал это, чтобы вывести объект 'dData' на экран, чтобы проверить структуру XML.

Я уверен, что ответ смотрит мне в лицо, но я просто не вижу этого!

Dave

ОБНОВЛЕНИЕ: Получил работу с приведенным ниже фрагментом кода:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().newDocument();

JAXBContext context = JAXBContext.newInstance(DailyData.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(dData, doc);


PayloadType payload = new PayloadType();
payload.getAny().add((Element)doc.getFirstChild());

Ответы [ 2 ]

1 голос
/ 05 мая 2010

Тип поля List<Element> обычно генерируется XJC, когда в схеме есть что-то подобное:

<xs:any processContents="skip" maxOccurs="unbounded" minOccurs="0" />

Ключ здесь processContents="skip", что означает "все идет" - любой хорошо сформированный XML может войти сюда. Поскольку это все для всех, все, что может сделать XJC, - это представить его как DOM, и ваша ответственность за управление этой полезной нагрузкой ложится на вас.

Если вы удалите processContents="skip", тогда JAXB попытается привязать полезную нагрузку к объектной модели, если она может сопоставить XML полезной нагрузки с классом в JAXBContext. В этом случае XJC сгенерирует это поле типа List<Object>.

Это может не показаться улучшением, но List может содержать Element (если JAXBContext не распознает полезную нагрузку как нечто, с чем он может связываться), или JAXBElement (если он распознает Это). Последний содержит связанную версию полезной нагрузки и намного проще в обращении.

Это все описано далее здесь .

Если вы не можете изменить схему и застряли с processContents="skip", то вам придется прыгать через обручи. Вы можете создать еще один JAXBContext, который знает о ваших классах полезной нагрузки, и использовать его для маршалинга в Element (используя что-то вроде marshaller.marshal(payload, new DOMResult()). Затем вы можете сбросить этот элемент в полезную нагрузку.

0 голосов
/ 04 мая 2010

Во-первых, любой тип элемента может содержать любой XML внутри него. Поэтому проверка схемы должна работать нормально, даже если вы добавите в нее XML-представление класса DailyData.

Теперь к вашему другому вопросу о маршалинге класса DailyData. Если бы этот класс был сгенерирован с использованием самого компилятора xjc, этот класс (или какой-либо другой сгенерированный класс) уже знал бы способ преобразования этого объекта в XML.

Я не использовал это напрямую, но следующая ссылка должна помочь вам

http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/rwbs_xjc.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...