XStream: предоставить вычисляемый одиночный тег для whole .xml

#xml #serialization #tags #xstream

#xml #сериализация #Теги #xstream

Вопрос:

Используя библиотеку XStream, моя структура .xml должна быть следующей:

 <record>value1</record>
         ...
<record>valueN</record>
<tailRecord>recordsCount</tailRecord>
  

tailRecord является последним и единственным тегом для всего файла .xml.
Он должен содержать количество record , поэтому должен быть вычисляемым.

Возможно ли предоставить вычисляемый тег с помощью XStream?
Общий вариант использования следующий:
когда выполняется действие пользователя, record должно быть добавлено, и tailRecord значение должно быть updated .

Комментарии:

1. Не могли бы вы опубликовать соответствующий фрагмент кода, который сериализуется <record> из вашего вывода? Я считаю, что это коллекция, и вам нужно добавить tailRecord свойство в ваш Java-компонент, которое содержит количество элементов в вашей коллекции.

2. команда $ xmlstarlet sel -t -v 'sum(//record)' file.xml печать суммы записей

Ответ №1:

Вам нужно будет внести незначительные изменения в вашу схему. Вместо:

 <record>value1</record>
<record>value2</record>
...
<record>valueN</record>
<tailRecord>recordsCount</tailRecord>
  

Вам понадобится:

 <records>
    <record>value1</record>
    <record>value2</record>
    ...
    <record>valueN</record>
</records>
<tailRecord>recordsCount</tailRecord>
  

…затем, если ваш объект выглядит примерно так:

 public class RecordObject
{
    private List<Integer> records;

    // ... a bunch of code

    public List<Integer> getRecords()
    {
        return records;
    }

    public int getRecordSize()
    {
        return records.size();
    }
}
  

Тогда две строки XStream — это все, что вам нужно:

 XStream xstream = new XStream();
RecordObject recordObject = (RecordObject)xstream.fromXML("your-xml-example-as-a-string");
  

XStream (по умолчанию) определит, что <record>value1</record> это узел типа int (или String , или любого другого очевидного примитивного типа). Затем он объединит несколько <record> объектов в java.utils.collections.List соответствующий тип автобокса.

Затем вы сможете использовать свой RecordObject , как обычно:

 System.out.println("There were " recordObject.getRecordCount()   " records found.");
  

Примечание: у вас может возникнуть проблема с элементом tailRecord XML. Я бы рекомендовал удалить его или настроить XStream так, чтобы он полностью игнорировал его с @XStreamOmitField помощью аннотации, как показано в этом примере.

Мой аргумент в пользу этого заключается в том, что правильный OOD никогда не позволит объекту содержать список объектов и иметь отдельное свойство, представляющее размер списка ( recordCount ) . Вы бы просто спроектировали объект (как в моем примере выше), чтобы иметь список этих объектов и иметь — самое большее — удобный метод, например getRecordCount() , для возврата размера списка во время выполнения.

Я понимаю, что по другим причинам (взаимодействие с устаревшими системами и т. Д.) Вам может понадобиться этот tailRecord элемент, Но команда проходит через XStream и становится добросовестным объектом Java, для него просто нет хорошего применения в Java.

И, если по какой-то причине я не понял ваш вопрос, и это не тот ответ, который вы ищете, моим последним предложением было бы проверить Smooks . Smooks реализует Visitor интерфейс и позволяет выполнять пользовательскую обработку каждый раз, когда узел XML посещается его внутренним SAXParser. Вы можете настроить его на запуск метода подсчета всякий раз, когда он достигает a tailRecord , и суммировать подсчеты, как вы этого хотите. Удачи вам!

Комментарии:

1. @sergionni Я был бы признателен за обратную связь относительно того, был ли этот ответ полезен для вас! Если нет, я могу вернуться к чертежным доскам.