2012-12-26 2 views
1

У меня есть класс, то есть что-то вроде этого:JAXB - значение поля элемента

public class Property { 

    private double floorArea; 

    public double getFloorArea() { 
     return floorArea; 
    } 

    @XmlElement 
    public void setFloorArea(double floorArea) { 
     this.floorArea = floorArea; 
    } 

} 

Который даст мне что-то вроде этого:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<property> 
    <floorArea>x</floorArea> 
</property> 

Но мне нужно что-то вроде этого:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<property> 
    <floorArea> 
     <value>x</value> 
    </floorArea> 
</property> 

API, который я использую, требует этого. Мои ограниченные знания JAXB мешают мне понять это. Любая помощь приветствуется.

EDIT:

что-то я исследую. Должен ли я создать класс value со своими аннотациями JAXB для этого? (и установить floorArea на тип value)?

+0

возможно дубликат [JAXB - маршализацию повторил вложенные классы] (http://stackoverflow.com/questions/13975632/jaxb-unmarshall-repeated-nested-classes) –

+0

@BlaiseDoughan: В этом случае я думаю, связь с методом решения предыдущего вопроса не будет столь очевидной для этого ОП, как для вас. Поскольку акцент здесь заключается в добавлении уровня вложенности к испускаемому XML, а не к хорошему способу захвата повторяющихся элементов, я бы сказал, что это почти дубликат, а не точный. Редактирование jsn's EDIT предлагает прогресс в правильном направлении, и я уверен, что некоторые поощрения будут оценены! – hardmath

+0

@hardmath - Я добавил ответ на этот вопрос, который должен помочь: http://stackoverflow.com/a/14101795/383861 –

ответ

3

Ниже, как ваш случай использования может быть поддержано с XmlAdapter использованием любой реализации JAXB (JSR-222).

XMLAdapter (DoubleValueAdapter)

XmlAdapter представляет собой механизм, который позволяет объекту быть преобразован в другой тип объекта. Затем это преобразованный объект, который преобразуется в/из XML.

package forum14045961; 

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

public class DoubleValueAdapter extends XmlAdapter<DoubleValueAdapter.AdaptedDoubleValue, Double>{ 

    public static class AdaptedDoubleValue { 
     public double value; 
    } 

    @Override 
    public AdaptedDoubleValue marshal(Double value) throws Exception { 
     AdaptedDoubleValue adaptedDoubleValue = new AdaptedDoubleValue(); 
     adaptedDoubleValue.value = value; 
     return adaptedDoubleValue; 
    } 

    @Override 
    public Double unmarshal(AdaptedDoubleValue adaptedDoubleValue) throws Exception { 
     return adaptedDoubleValue.value; 
    } 

} 

недвижимости

@XmlJavaTypeAdapter аннотаций используется для указания XmlAdapter. Мне нужно было изменить double на Double, поэтому я переместил отображение в поле, чтобы не повлиять на публичный API.

package forum14045961; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

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

    @XmlJavaTypeAdapter(DoubleValueAdapter.class) 
    private Double floorArea; 

    public double getFloorArea() { 
     return floorArea; 
    } 

    public void setFloorArea(double floorArea) { 
     this.floorArea = floorArea; 
    } 

} 

Demo

Ниже некоторые демо-код, чтобы доказать, что все работает.

package forum14045961; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Property.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum14045961/input.xml"); 
     Property property = (Property) unmarshaller.unmarshal(xml); 

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

} 

Input.xml/Выход

Ниже приведен вход и выход из демонстрационного кода.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<property> 
    <floorArea> 
     <value>1.23</value> 
    </floorArea> 
</property> 
2

Ваша догадка правильная, описанный способ генерирует xml, как вы показали.

public class Property { 

    @XmlElement(required = true) 
    protected FloorArea floorArea; 
    public FloorArea getFloorArea() { 
     return floorArea; 
    } 
    public void setFloorArea(FloorArea value) { 
     this.floorArea = value; 
    } 
} 

И ваш класс FloorArea будет выглядеть примерно как снимок кода ниже.

public class FloorArea { 

    @XmlElement(required = true) 
    protected String value; 
    public String getValue() { 
     return value; 
    } 
    public void setValue(String value) { 
     this.value = value; 
    } 
} 
+0

Это решение. Но это не сработало. Я написал свою легкую версию JAXB. Благодарю. – jn1kk

+0

@jsn - Я добавил 2 ответа. Во-первых, как идея из этого ответа может быть скрыта за «XmlAdapter» (см. Http://stackoverflow.com/a/14101795/383861). Второй использует расширение '@ XmlPath' в EclipseLink JAXB (MOXy) (см. Http://stackoverflow.com/a/14101682/383861) –

3

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

Ниже, как можно сопоставить случай использования с помощью Moxy в @XmlPath расширение:

Недвижимость

package forum14045961; 

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlPath; 

@XmlRootElement 
public class Property { 

    private double floorArea; 

    public double getFloorArea() { 
     return floorArea; 
    } 

    @XmlPath("floorArea/value/text()") 
    public void setFloorArea(double floorArea) { 
     this.floorArea = floorArea; 
    } 

} 

jaxb.properties

Чтобы указать Moxy как ваш JAXB (JSR- 222) вам необходимо включить файл с именем jaxb.properties в том же пакете, что и ваша модель домена, со следующей записью (см. http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

Demo

только стандартные интерфейсы API JAXB во время выполнения требуется, чтобы прочитать объекты и записать их обратно в XML, когда Moxy используется в качестве поставщика JAXB.

package forum14045961; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Property.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum14045961/input.xml"); 
     Property property = (Property) unmarshaller.unmarshal(xml); 

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

} 

Input.xml/Выход

Ниже приведен вход и выход от запуска демонстрационного кода.

<?xml version="1.0" encoding="UTF-8"?> 
<property> 
    <floorArea> 
     <value>1.23</value> 
    </floorArea> 
</property> 

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

+0

Я действительно посмотрел MOXy и попытался его использовать, но библиотека была очень большой (по размеру) по сравнению с оригинальной библиотекой JAXB. Спасибо за ответ! – jn1kk

+0

@jsn - В настоящее время мы реорганизуем MOXy, чтобы у него было гораздо меньше банки. Если вы последуете за мной на Twitter http://twitter.com/bdoughan или через мой блог http://blog.bdoughan.com, вы увидите обновления о его прогрессе. –

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