VDT2
@VDT2
Java Junior

Как правильнее указывать атрибуты для тегов в JAXB?

Приветствую господа!
У меня вопрос по реализации след. задачи. Пример из учебника...
Есть код
@XmlType( propOrder = { "name", "capital", "foundation", "continent" , "population"} )
@XmlRootElement( name = "Country" )
public class Country
{
     
    @XmlElement (name = "Country_Population")
    public void setPopulation( int population )
    {
        this.population = population;
    }
 
 
    @XmlElement( name = "Country_Name" )
    public void setName( String name )
    {
        this.name = name;
    }
 
    @XmlElement( name = "Country_Capital" )
    public void setCapital( String capital )
    {
        this.capital = capital;
    }
    @XmlAttribute( name = "importance", required = true )
    public void setImportance( int importance )
    {
        this.importance = importance;
    }
...


Который после маршалинга выдает:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Country importance="1">
 <Country_Name>Spain</Country_Name>
 <Country_Capital>Madrid</Country_Capital>
 <Country_Foundation_Date></Country_Foundation_Date>
 <Country_Continent>Europe</Country_Continent>
 <Country_Population>45000000</Country_Population>
</Country>


А мне нужно получить вывод примерно след:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Country importance="1">
 <Country_Name>Spain</Country_Name>
 <Country_Capital>Madrid</Country_Capital>
 <Country_Foundation_Date></Country_Foundation_Date>
 <Country_Continent name="Europe"/>
 <Country_Population value="45000000"/>
</Country>


Т.е. в некоторых тегах значения должны указываться в АТРИБУТАХ.
Указания нескольких "@XmlAttribute" приводит к выводу их всех в одном теге (В данном случае это "Country").

Это что ж получается.... Что мне нужно на каждый подобный случай "",
Создавать отдельный объект (класс) типа "Country_Continent"?

Или все же есть более изящное и простое решение, не видимое моим взором на просторах интерентов?

Спасибо
  • Вопрос задан
  • 63 просмотра
Решения вопроса 2
@Ryabos
Аннотации JAXB указывают на принадлежность к классу, в котором они объявлены. То есть если Вы указываете @XmlAttribute, то атрибут будет добавлен именно к классу

Чтобы использовать более "тонкую" конфигурацию маршаллинга, создайте класс для каждого тега, и храните ссылку на объект этого класса в поле основного класса
Ответ написан
VDT2
@VDT2 Автор вопроса
Java Junior
И так РЕШЕНИЕ ЗАДАЧИ.
ДАНО:
<?xml version="1.0" encoding="UTF-8"?>
<types>
    <type name="Бинт">
        <nominal>5</nominal>
        <category name="медикаменты"/>
    </type>    
</types>


Для того, чтобы использовать аннтацию "name" для тега category который является вложенным в тег с аннотацией , нужно создавать для такого тега (category) отдельный класс

class Category
public class Category
{
    private String name;

    public String getName ()
    {
        return name;
    }
    
    @XmlAttribute(name = "name") //добавили аннотацию name ( name="медикаменты")
    public void setName (String name)
    {
        this.name = name;
    }
}


class Type
public class Type
{
    private String nominal;

    private String name;

    private Category category;

    public String getNominal ()
    {
        return nominal;
    }

    public void setNominal (String nominal)
    {
        this.nominal = nominal;
    }

    public String getName ()
    {
        return name;
    }
    @XmlAttribute(name = "name") //атрибут NAME для имени тега type (name="Бинт")
    public void setName (String name)
    {
        this.name = name;
    }

    public Category getCategory ()
    {
        return category;
    }

    public void setCategory (Category category)
    {
        this.category = category;
    }
}


class Types
@XmlSeeAlso({Type.class})
@XmlRootElement( name = "types" )
public class Types
{

    List<Type> types;

    public List<Type> gettypes()
    {
        return types;
    }

    /**
     * element that is going to be marshaled in the xml
     */
    @XmlElement( name = "type" )
    public void settypes( List<Type> types )
    {
        this.types = types;
    }

    /**
     * This method is not used by jaxb, just used for business reasons. In the case that this class
     * would be generated using xml schemas definitions, this method has to be added to the
     * generated class or to some helper or util one
     *
     * @param Type
     */
    public void add( Type Type )
    {
        if( this.types == null )
        {
            this.types = new ArrayList<Type>();
        }
        this.types.add( Type );

    }

    @Override
    public String toString()
    {
        StringBuffer str = new StringBuffer();
        for( Type museum : this.types )
        {
            str.append( museum.toString() );
        }
        return str.toString();
    }
    
}


Далее магия маршалинга. Теперь чтобы эту дичь запаковать нужно в main class сделать следующее

Category category = new Category(); //Создали объект Категории для объекта type
            category.setName("медикаменты"); //Прописали атрибут

            Type type = new Type(); //Создаем объект TYPE.
            type.setName("Бинт"); //Прописываем ему имя
            type.setNominal("5"); // какие то данные в тег Nominal
            type.setCategory(category); // добавили ссылку на объект Категории

            Types types = new Types(); // создали "основной" объект
             types.add(type);  // положили в него все объекты типа Тайп (у нас он один)
//             types.add(type2);  // так добавляем еще типы.

            JAXBContext jaxbContext = JAXBContext.newInstance( Types.class); //Указываем только "корневой" класс. Тот что самый верхний в иерархии (куда мы все и сложили)
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            
            jaxbMarshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );

            jaxbMarshaller.marshal( types, new File( "test.xml" ) ); //сохранили в файл
            jaxbMarshaller.marshal( types, System.out ); //показали в консоли чего там в файл сохранили.


Готово.
p.s. Дожили. Я пишу инструкции и примеры кода. А жизнь то меняется....)))
p.p.s. Изменил код class Types. Там была ошибка приводящая не корректному результату при маршалинге.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
The AnyLogic Company Санкт-Петербург
от 180 000 ₽
от 150 000 до 400 000 ₽
DATS.TEAM Москва
от 200 000 до 350 000 ₽
09 мар. 2021, в 10:24
3000 руб./за проект
09 мар. 2021, в 10:22
5000 руб./за проект
09 мар. 2021, в 09:57
90000 руб./за проект