XStream: преобразовать коллекцию с атрибутами

XML, который я пытаюсь преобразовать, выглядит так:

<numberOfEmployees year="2013">499.0</numberOfEmployees>

Согласно XSD, таких тегов может быть несколько, так что это коллекция. Сгенерированный код выглядит так:

    protected List<NumberOfPersonnel> numberOfEmployees;

Когда я использую @XStreamImplicit, значение сбрасывается, поэтому мне нужен преобразователь. Но объединение @XStreamImplicit с @XStreamConverter, похоже, не работает.

Итак, как мне это сделать? Я пытался возиться со своим собственным конвертером, который наследуется от CollectionConverter, но он утверждает, что не находит дочерних элементов, и, честно говоря, я понятия не имею, что делаю.

Может ли кто-нибудь просветить меня? Это не должно быть так сложно, не так ли?


person mcv    schedule 12.07.2013    source источник


Ответы (1)


Я могу заставить его работать, используя ToAttributedValueConverter в классе NumberOfPersonnel и @XStreamImplicit в списке. -ценное имущество:

NumberOfPersonnel.java

import com.thoughtworks.xstream.annotations.*;
import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;

// treat the "value" property as the element content and all others as attributes
@XStreamConverter(value = ToAttributedValueConverter.class, strings = {"value"})
public class NumberOfPersonnel {
  public NumberOfPersonnel(int year, double value) {
    this.year = year;
    this.value = value;
  }

  private int year;

  private double value;

  public String toString() {
    return year + ": " + value;
  }
}

Container.java

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.*;
import java.util.List;
import java.util.Arrays;
import java.io.File;

@XStreamAlias("container")
public class Container {
  private String name;

  // any element named numberOfEmployees should go into this list
  @XStreamImplicit(itemFieldName="numberOfEmployees")
  protected List<NumberOfPersonnel> numberOfEmployees;

  public Container(String name, List<NumberOfPersonnel> noEmp) {
    this.name = name;
    this.numberOfEmployees = noEmp;
  }

  public String toString() {
    return name + ", " + numberOfEmployees;
  }

  public static void main(String[] args) throws Exception {
    XStream xs = new XStream();
    xs.processAnnotations(Container.class);

    System.out.println("Unmarshalling:");
    System.out.println(xs.fromXML(new File("in.xml")));

    System.out.println("Marshalling:");
    System.out.println(xs.toXML(new Container("World",
           Arrays.asList(new NumberOfPersonnel(2001, 1000),
                         new NumberOfPersonnel(2002, 500)))));
  }
}

в формате XML

<container>
  <name>Hello</name>
  <numberOfEmployees year="2013">499.0</numberOfEmployees>
  <numberOfEmployees year="2012">550.0</numberOfEmployees>
</container>

Вывод

Unmarshalling:
Hello, [2013: 499.0, 2012: 550.0]
Marshalling:
<container>
  <name>World</name>
  <numberOfEmployees year="2001">1000.0</numberOfEmployees>
  <numberOfEmployees year="2002">500.0</numberOfEmployees>
</container>
person Ian Roberts    schedule 15.07.2013
comment
Спасибо! Это делает именно то, что мне нужно, гораздо более элегантным способом, чем я пытался сделать. Также похоже, что все пользовательские конвертеры, написанные коллегой, не нужны и должны быть заменены этим. - person mcv; 16.07.2013