I must parse a XML file that can be two types:
<property>
<value>Some text</value>
</property>
and
<property>
<value>
<item id="first_id"/>
<item id="second_id"/>
<item id="third_id"/>
</value>
</property>
How can I do this with Java?
I created a class:
@Root(strict = false)
public class PropertyValue {
@ElementList(inline = true, required = false)
private List<ItemData> items;
@Text(required = false)
private String text;
}
ItemData
is item
class.
But this does not work. The code gives me an exception:
org.simpleframework.xml.core.TextException: Text annotation @org.simpleframework.xml.Text(data=false, empty=, required=false) on field 'text' private java.lang.String PropertyValue.text used with elements in class PropertyValue
I solved the problem!
I used the following question answer: Deserializing an XML tag with text AND subtags using Retrofit
I created a class that convert the XML files as I want (sorry for my code :-( ):
public class PropertyValueConverter implements Converter<PropertyValue> {
@Override
public PropertyValue read(InputNode node) throws Exception {
PropertyValue propertyValue = new PropertyValue();
List<ItemData> propertyValueItems = new ArrayList<>();
String propertyValueText = "";
InputNode itemNode = node.getNext("item");
while (itemNode != null) {
String itemId = itemNode.getAttribute("id").getValue();
ItemData itemData = new ItemData();
itemData.setId(itemId);
propertyValueItems.add(itemData);
itemNode = node.getNext("id");
}
if (propertyValueItems.size() == 0) {
propertyValueText = node.getValue();
}
propertyValue.setItems(propertyValueItems);
propertyValue.setText(propertyValueText);
return propertyValue;
}
@Override
public void write(OutputNode node, PropertyValue value) throws Exception {
}
}
Then I changed PropertyValue
class:
@Root(strict = false)
@Convert(value = PropertyValueConverter.class)
public class PropertyValue {
private List<ItemData> items;
private String text;
public List<ItemData> getItems() {
return items;
}
public void setItems(List<ItemData> items) {
this.items = items;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Then I set SimpleXml converter factory:
private static Strategy strategy = new AnnotationStrategy();
private static Serializer serializer = new Persister(strategy);
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(SimpleXmlConverterFactory.create(serializer));
So, It works for me.