Демаршалинг в JAXB

У меня есть следующий файл tester.xml, который содержит некоторую информацию о событиях.

<?xml version="1.0"?>

<resultset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
    <field name="esid">539661</field>
    <field name="esname">Title 01</field>
    <field name="eslink">http://www.some_event_link.com</field>
    <field name="estext">Event description 01</field>
    <field name="esinfo" xsi:nil="true" />
    <field name="espicture_small">http://www.some_event_link.com/media/small_image.jpg</field>
    <field name="espicture">http://www.some_event_link.com/media/some_image..gif</field>
    <field name="espicture_big">http://www.some_event_link.com/media/big_image.jpg</field>
    <field name="esbegin">2000-11-22</field>
    <field name="esend">2011-12-15</field>
    <field name="eventid">1379305</field>
    <field name="eventname">Event name 01</field>
    <field name="eventdate">2011-10-12</field>
    <field name="eventtime">19:00:00</field>
    <field name="eventlink">http://www.mysite.com/tickets.html</field>
    <field name="eventvenue">Event venue 01</field>
</row>
<row>
    <field name="esid">539636</field>
    <field name="esname">Title 02</field>
    <field name="eslink">http://www.some_event_link.com</field>
    <field name="estext">Event description 02</field>
    <field name="esinfo" xsi:nil="true" />
    <field name="espicture_small">http://www.some_event_link.com/media/small_image.jpg</field>
    <field name="espicture">http://www.some_event_link.com/media/some_image..gif</field>
    <field name="espicture_big">http://www.some_event_link.com/media/big_image.jpg</field>
    <field name="esbegin">2000-10-10</field>
    <field name="esend">2011-11-01</field>
    <field name="eventid">1379081</field>
    <field name="eventname">Event name 01</field>
    <field name="eventdate">2011-10-12</field>
    <field name="eventtime">14:00:00</field>
    <field name="eventlink">http://www.mysite.com/tickets.html</field>
    <field name="eventvenue">Event venue 02</field>
</row>

Also I have my XML mapping classes as follows.
First is the class corresponding to the tag < resultset >

package com.wapice.xml.beans;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement(name = "resultset")
 public class Resultset {

  private ArrayList<Row> rowsList;


  @XmlElement(required = true, name = "row")
  public ArrayList<Row> getRowsList() {
    return rowsList;
  }


  public void setRowsList(ArrayList<Row> rowsList) {
    this.rowsList = rowsList;
  }

}

Далее идет класс, соответствующий тегу ‹ row >

package com.wapice.xml.beans;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


@XmlRootElement(name = "row")
@XmlType(propOrder = {"field"})
public class Row {

    private String field;


    @XmlElement(required = true, name = "field")
    public String getField() {
      return field;
    }


    public void setField(String field) {
      this.field = field;
    }

}

Я попытался преобразовать этот xml в объекты и распечатать имена и значения полей на моей консоли с помощью следующего фрагмента кода.

try {
    JAXBContext context = JAXBContext.newInstance(Resultset.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    Resultset resultSet = (Resultset)unmarshaller.unmarshal(new FileReader("tester.xml"));

    for(Row row : resultSet.getRowsList()){
    System.out.println("Field : " +row.getField());
    }
} 
catch (JAXBException e) {
    e.printStackTrace();
} 
catch (IOException e) {
    e.printStackTrace();
}

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

Field : Event venue 01
Field : Event venue 02

Может кто-нибудь, пожалуйста, скажите мне, что я здесь делаю неправильно, и было бы очень признательно, если бы кто-нибудь сказал мне, как распечатать все мои поля ‹ > вместе с их именами и значениями.

Заранее спасибо.
Асела.


person Asela    schedule 17.11.2011    source источник


Ответы (2)


Вы можете ввести объект Field:

package com.wapice.xml.beans;

import javax.xml.bind.annotation.*;

public class Field {
    @XmlAttribute name;
    @XmlValue value;
}

И пусть объект Row удерживает список из них:

package com.wapice.xml.beans;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


@XmlRootElement(name = "row")
@XmlType(propOrder = {"field"})
public class Row {

    private List<Field> fields;

    @XmlElement(required = true, name = "field")
    public List<Field> getFields() {
      return field;
    }

    public void setField(List<Field> fields) {
      this.fields = fields;
    }

}

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

person bdoughan    schedule 17.11.2011

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

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "rowsList"
this problem is related to the following location:
    at public java.util.ArrayList com.wapice.xml.beans.Resultset.getRowsList()
    at com.wapice.xml.beans.Resultset
this problem is related to the following location:
    at private java.util.ArrayList com.wapice.xml.beans.Resultset.rowsList
    at com.wapice.xml.beans.Resultset
Class has two properties of the same name "fieldsList"
this problem is related to the following location:
    at public java.util.ArrayList com.wapice.xml.beans.Row.getFieldsList()
    at com.wapice.xml.beans.Row
    at private java.util.ArrayList com.wapice.xml.beans.Resultset.rowsList
    at com.wapice.xml.beans.Resultset
this problem is related to the following location:
    at private java.util.ArrayList com.wapice.xml.beans.Row.fieldsList
    at com.wapice.xml.beans.Row
    at private java.util.ArrayList com.wapice.xml.beans.Resultset.rowsList
    at com.wapice.xml.beans.Resultset

Затем я изменил имена соответствующих геттеров/сеттеров, и все заработало нормально. Ниже показано, как я изменил его.

----------------
Class Resultset
----------------

@XmlElement(required = true, name = "row")
private ArrayList<Row> rowsList; // I kept the same name for this attribute


public ArrayList<Row> getRowsList() { // I changed this to getRows()
return rowsList;
}


public void setRowsList(ArrayList<Row> rowsList) { // I changed this to setRows()
this.rowsList = rowsList;
}


----------
Class Row
----------

@XmlElement(required = true, name = "field")
private ArrayList<Field> fieldsList;  // I kept the same name for this attribute


public void setFieldsList(ArrayList<Field> fieldsList) { // I changed this to getFields()
this.fieldsList = fieldsList;
}

public ArrayList<Field> getFieldsList() { // I changed this to setFields()
return fieldsList;
}

Надеюсь, это поможет кому-то еще.

person Asela    schedule 18.11.2011
comment
Исключение возникало из-за того, что тип доступа по умолчанию — PUBLIC_MEMBER, и поскольку аннотация была в поле, JAXB считал, что у вас есть и поле, и свойство, сопоставленное с одним и тем же элементом XML. Вам поможет следующая статья: blog.bdoughan.com/ 2011/06/using-jaxbs-xmlaccessortype-to.html - person bdoughan; 18.11.2011