связывание значения XML в качестве атрибута или элемента - PullRequest
3 голосов
/ 07 июля 2011

Синтаксис XML в Spring Framework несколько гибкий. Это позволяет вам определять некоторую информацию либо как атрибут, либо как вложенный элемент. Например.,

<property name="accountDao" ref="accountDao"/>

или

<property name="accountDao">
    <ref bean="accountDao">
</property>

Я хочу сделать что-то подобное в моем коде

<a b="foo">

и

<a>
    <attr name="b">foo</attr>
</a>

Цель состоит в том, чтобы предоставить пользователю простоту использования атрибутов до точки, где имя атрибута слишком сложное (например, содержит пробел) или значение является многострочным. Но есть одна загвоздка: я хочу использовать некоторую среду связывания или сериализации, такую ​​как xstream или jaxb, вместо обычного stax или dom apis, в котором мне приходится вручную просматривать весь xml и создавать свои объекты.

До сих пор я не выяснил, как определить такие отображения с помощью xstream или jaxb, от поля Java до двух мест в xml.

Я пытался использовать xjc (java 6 jvm) с Spring's xsd . Я думал, может быть, я найду некоторые идеи в сгенерированных объектах. Тем не менее, xjc не удалось с некоторыми ошибками.

Есть еще идеи?

1 Ответ

1 голос
/ 07 июля 2011

Примечание: Я являюсь лидером EclipseLink JAXB (MOXy) и членом группы экспертов JAXB 2.X ( JSR-222 ).

Вы можете использовать XML-метаданные MOXy для этого варианта использования, чтобы применить несколько привязок к полю / свойству:

binding.xml

Метаданныепоставляется через формат метаданных XML MOXy.Эти метаданные дополняют то, что предоставляется с помощью аннотаций JAXB и MOXy:

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="example">
    <java-types>
        <java-type name="A">
            <xml-root-element/>
            <java-attributes>
                <xml-attribute java-attribute="b"/>
                <xml-element java-attribute="b" xml-path="attr[@name='b']/text()" read-only="true"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Демо

Следующий код демонстрирует, как запустить реализацию JAXBContext на языке MOXy с помощью файла отображения.

package example;

import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo {

    private static final String ATTRIBUTE_XML = "<a b='foo'/>";
    private static final String ELEMENT_XML = "<a><attr name='b'>bar</attr></a>";

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "example/binding.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {A.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        A a1 = (A) unmarshaller.unmarshal(new StringReader(ATTRIBUTE_XML));
        marshaller.marshal(a1, System.out);

        A a2 = (A) unmarshaller.unmarshal(new StringReader(ELEMENT_XML));
        marshaller.marshal(a2, System.out);
    }

}

A

package example;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class A {

    private String b;

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

}

Вывод

Несмотря на то, что MOXy может разархивировать различные форматы, маршалформат тот же.

<?xml version="1.0" encoding="UTF-8"?>
<a b="foo"/>
<?xml version="1.0" encoding="UTF-8"?>
<a b="bar"/>

для получения дополнительной информации

...