Skip a tag related to a List with XStream

1.8k views Asked by At

I'm trying to convert a class' instance into an XML with XStream. Everything works fine, except for a thing, that I hope someone could help me to solve.

As a premise, I have many "nested" classes (in the order, OrderStatusImport -> OrderCollection -> Order -> OrderLine), but the focal point is represented by the class Order; as expressed above, each instance of it contains a List of OrderLine objects. Simply like this:

public class Order {
   //attribute's declarations...
   ArrayList<OrderLine> orderLines;
}

This is my formatter class, in which I call the main XStream logic:

private String createImportXml(OrderStatusImport orderStatusImport) {
    Object xstream = null;
    if (xstream == null) {
        xstream = new XStream() {
            @Override
            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new UpperCaseMapper(next);
            }
        };
    }

    ((XStream) xstream).alias("OrderStatusImport", OrderStatusImport.class);
    ((XStream) xstream).alias("OrderCollection", OrderCollection.class);
    ((XStream) xstream).alias("Order", Order.class);
    ((XStream) xstream).alias("OrderLine", OrderLine.class);
    ((XStream) xstream).omitField(Order.class, "OrderLines");

    String decl = "\n";
    String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    String xml = "";

    xml += ((XStream) xstream).toXML(orderStatusImport);

    return (header + decl + xml + decl);
}

The problem is that the resulting XML has the unwanted tag OrderLines. It is presented as:

  <Order>
    <OrderItemsTotal>266.00</OrderItemsTotal>
    <OrderShipping>0.00</OrderShipping>
    <OrderCodFee>0.00</OrderCodFee>
    <OrderTotal>266.00</OrderTotal>
    <OrderStatus>H4</OrderStatus>
    <OrderLines>
      <OrderLine>
        <ItemNumber>000001</ItemNumber>
        <DCNumber>DC10</DCNumber>
        <StorageLocation>1001</StorageLocation>
        <OrderLineStatus>C0</OrderLineStatus>
        <CancelReasonCode></CancelReasonCode>
        <Quantity>1</Quantity>
        <ItemTotal>167.00</ItemTotal>
      </OrderLine>
      <OrderLine>
        <ItemNumber>000002</ItemNumber>
        <DCNumber>DC10</DCNumber>
        <StorageLocation>1001</StorageLocation>
        <OrderLineStatus>C0</OrderLineStatus>
        <CancelReasonCode></CancelReasonCode>
        <Quantity>1</Quantity>
        <ItemTotal>99.00</ItemTotal>
      </OrderLine>
    </OrderLines>
  </Order>

, while I want this (without OrderLines tags):

  <Order>
    <OrderItemsTotal>266.00</OrderItemsTotal>
    <OrderShipping>0.00</OrderShipping>
    <OrderCodFee>0.00</OrderCodFee>
    <OrderTotal>266.00</OrderTotal>
    <OrderStatus>H4</OrderStatus>
    <OrderLine>
       <ItemNumber>000001</ItemNumber>
       <DCNumber>DC10</DCNumber>
       <StorageLocation>1001</StorageLocation>
       <OrderLineStatus>C0</OrderLineStatus>
       <CancelReasonCode></CancelReasonCode>
       <Quantity>1</Quantity>
       <ItemTotal>167.00</ItemTotal>
     </OrderLine>
     <OrderLine>
       <ItemNumber>000002</ItemNumber>
       <DCNumber>DC10</DCNumber>
       <StorageLocation>1001</StorageLocation>
       <OrderLineStatus>C0</OrderLineStatus>
       <CancelReasonCode></CancelReasonCode>
       <Quantity>1</Quantity>
       <ItemTotal>99.00</ItemTotal>
     </OrderLine>
  </Order>

I have tried both with omitField() than with the @XStreamOmitField annotation, but maybe I misunderstand these ones (I'm a newbie in XStream). Before you mention that, I could also use a simple replace() on the resulting String, but I don't know how to preserve the indentation this way.

1

There are 1 answers

2
Dalija Prasnikar On BEST ANSWER

What you want is called implicit collection. You can define it in two ways

by using annotation

public class Order {
   @XStreamImplicit(itemFieldName="OrderLine")
   ArrayList<OrderLine> orderLines;
}

or using code

xstream.addImplicitCollection(Order.class, "orderLines", "OrderLine", OrderLine.class);