XStream - вызов добавлению атрибута к дочернему элементу

Мне трудно добавить атрибут к дочернему элементу для записи XML-файла. Проблема, по крайней мере для меня, заключается в том, что POJO, которому сопоставлен элемент, связан с родительским элементом. Я хочу, чтобы вывод XML выглядел так:

<TXLife version="2.42.00" xmlns="http://ACORD.org/Standards/Life/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <TXLifeRequest>
    <TransRefGUID>906D67C1-CC4D-11CF-91FB-444554540000</TransRefGUID>
    <TransType tc="1203"></TransType>
    <TransExeDate>2020-01-06</TransExeDate>
    <TransExeTime>09:30:00</TransExeTime>
    ...multiple other parent and child elements..
  </TXLifeRequest>
</TXLife>

Это элемент TransType, в который мне нужно добавить атрибут (как показано выше).

ПОХОС:

@XStreamAlias("TXLife")
public class TXLife {

    @XStreamAsAttribute
    private String version;

    @XStreamAsAttribute
    final String xmlns = "http://ACORD.org/Standards/Life/2";

    @XStreamAsAttribute
    @XStreamAlias("xmlns:xsi")
    final String xlink="http://www.w3.org/2001/XMLSchema-instance";

    @XStreamImplicit
    private List<TXLifeRequest> transListings = new ArrayList<TXLifeRequest>();

    public TXLife() {
        super();
    }
...getters and setters
@XStreamAlias("TXLifeRequest")
public class TXLifeRequest {

    @XStreamAlias("TransRefGUID")
    private String transRefGUID;

    @XStreamAlias("TransType")
    private String transType;

    @XStreamAlias("TransExeDate")
    private String transExeDate;

    @XStreamAlias("TransExeTime")
    private String transExeTime;

    public TXLifeRequest(String transRefGUID, String transType, String transExeDate, String transExeTime) {
        this.transRefGUID = transRefGUID;
        this.transType = transType;
        this.transExeDate = transExeDate;
        this.transExeTime = transExeTime;
    }
...getters and setters

Конвертер:

public class TransTypeAttributeConverter implements Converter {

    @Override
    public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
        TXLifeRequest txLifeRequest = (TXLifeRequest) o;
        hierarchicalStreamWriter.addAttribute("tc", "1203");
        hierarchicalStreamWriter.setValue("");
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
        return null;
    }

    @Override
    public boolean canConvert(Class type) {
        return type.equals(TXLifeRequest.class);
    }
}

Тестовый класс:

public class TestXMLOutput {

    public static void main(String[] args) throws UnsupportedEncodingException {

        TestXMLOutput testXMLOutput = new TestXMLOutput();

        TXLife txLife = new TXLife();
        txLife.setVersion("2.42.00");
        txLife.add(new TXLifeRequest("906D67C1-CC4D-11CF-91FB-444554540000", "",
                "2020-01-06", "09:30:00"));

        testXMLOutput.testConvertAndWriteXMLToFile(txLife);

    }

    public void testConvertAndWriteXMLToFile(TXLife txLife) throws UnsupportedEncodingException {
        XStream xstream = new XStream(new StaxDriver());
        xstream.processAnnotations(TXLife.class);
        xstream.alias("TXLife", TXLife.class);
        xstream.processAnnotations(TXLifeRequest.class);
        xstream.alias("TXLifeRequest", TXLifeRequest.class);

        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream("CITS_BoB/src/test/java/txlife.xml"));
        } catch (IOException e) {
            System.out.println("IOException Occurred: " + e.getMessage());
        }

        xstream.addImplicitCollection(TXLife.class, "transListings");
        //xstream.registerConverter(new TransTypeAttributeConverter());

        xstream.marshal(txLife, new PrettyPrintWriter(
                new OutputStreamWriter(bos, StandardCharsets.UTF_8)));


    }
}

Я обнаружил, что запуск как xstream.addImplicitCollection (...), так и xstream.registerConverter (...) в тестовом классе дает следующий вывод XML:

<TXLife version="2.42.00" xmlns="http://ACORD.org/Standards/Life/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <TXLifeRequest tc="1203"></TXLifeRequest>
</TXLife>

Я уверен, что неправильно понял или вообще упустил, как правильно использовать xstream для выполнения такого рода задач. В любых примерах, которые я нашел в Интернете, элемент, к которому добавлен атрибут, сопоставлен с классом, тогда как в моем случае элемент, к которому я хочу добавить атрибут, сам находится в классе, который сопоставлен с «родительским» элементом. Я просмотрел веб-сайт xstream, но не нашел здесь ни одного примера, напрямую связанного с моей целью. К сожалению, JAXB не подходит, поскольку я использую openjdk 12, который его не поддерживает. Я не знаю, есть ли в openjdk 12 средство записи XML-документов (я все еще новичок в этой версии). Я предполагаю, что я не могу понять, как каким-то образом «связать» конкретный дочерний элемент в POJO TXLifeRequest с атрибутом, который я хочу добавить к нему. Прошу извинить меня за неправильное использование кода, например, строковые литералы, добавленные в ierarchicalStreamWriter.addAttribute ("tc", "1203"); в оператор TransTypeAttributeConverter. Я конечно, находятся в неправильном контексте или в неправильном месте. Если кто-то может пролить свет на это, мы будем очень признательны. Спасибо!

Извините, я также должен добавить, что другие варианты, которые я рассмотрел, - это написать POJO для каждого элемента (что, как я понимаю, вероятно, крайне и неэффективно) или сопоставить дочерний элемент в POJO с внутренним классом, чтобы он фактически стал это собственный родительский элемент.


person Randy    schedule 13.01.2020    source источник


Ответы (1)


В итоге я использовал синтаксический анализатор java DOM в качестве решения, которое позволило мне установить атрибут непосредственно в элементе TransType. Если случайно кто-то знает, как решить эту проблему в XStream, мне все равно было бы интересно узнать. Ваше здоровье.

person Randy    schedule 15.01.2020