2

一般的な XmlJavaTypeAdapter を使用して、いくつかの xml を Guava の Optional にラップされた Java オブジェクトに非整列化しようとしています。ただし、ジェネリックを使用して正しく動作させることはできません。

私はeclipselink 2.5.1/moxyを使用しています

XML:

<?xml version="1.0" encoding="UTF-8"?>
<page>
    <label>Test</label>
    <description>Test</description>
</page>

Page.java:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.eclipse.persistence.oxm.annotations.XmlPath;

import com.google.common.base.Optional;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement()
public class Page {

    @XmlPath("label")
    private Label label;

    @XmlJavaTypeAdapter(OptionalLabelAdapter.class)
    private Optional<Label> description = Optional.absent();

}

ラベル.java:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlValue;

@XmlAccessorType(XmlAccessType.FIELD)
public class Label {
    @XmlValue
    private String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

MoxyTest.java:

import java.io.File;

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

public class MoxyTest {

    public static void main(String[] args) throws JAXBException {   
        String name = "test";

        JAXBContext jc = JAXBContext.newInstance(Page.class);
        System.out.println(jc.getClass());

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Page page = (Page) unmarshaller.unmarshal(new File("xml/" + name + ".xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(page, System.out);
    }

}

これは、ジェネリックを使用した私のアダプターです。

import javax.xml.bind.annotation.adapters.XmlAdapter;

import com.google.common.base.Optional;

public class OptionalAdapter<T> extends XmlAdapter<T, Optional<T>> {

    @Override
    public Optional<T> unmarshal(T value) throws Exception {
        return Optional.of(value);
    }

    @Override
    public T marshal(final Optional<T> value) throws Exception {
        if(value.isPresent()){
            return value.get();
        } else {
            return null;
        }  
    }

}

これは機能しません。オプションでラップされた ElementNSImpl を取得します。私が使用すると動作します:

@XmlJavaTypeAdapter(OptionalAdapter.class)
@XmlElement(name = "description", type = Label.class)
private Optional<Label> description;

Page.java で。ただし、属性で同じことを達成する方法がわかりません。

このアダプターを使用すると機能します。

import javax.xml.bind.annotation.adapters.XmlAdapter;

import com.google.common.base.Optional;

public class OptionalLabelAdapter extends XmlAdapter<Label, Optional<Label>> {

    @Override
    public Optional<Label> unmarshal(final Label value) throws Exception {
        return Optional.of(value);
    }

    @Override
    public Label marshal(final Optional<Label> value) throws Exception {
        if(value.isPresent()){
            return value.get();
        } else {
            return null;
        }  
    }

}

「@XmlElement(name = "description", type = Label.class)」がないと汎用アダプターが機能しない理由を説明し、要素ではなく属性で同じことを達成する方法を説明してください。

4

0 に答える 0