#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 Я был бы признателен за обратную связь относительно того, был ли этот ответ полезен для вас! Если нет, я могу вернуться к чертежным доскам.