Tag duplicada com XStream

Olá pessoal,

Estou tendo duplicação de tags em meu XML durante serialização com XStream. A tag duplicada é a de impostos. Por que está sendo duplicada?

<balanco>
  <id>1</id>
  <compras>
    <operacao>
      <impostos>
        <impostos>
          <descricao>ICMS</descricao>
          <estado>Sao Paulo</estado>
          <cidade>Garulhos</cidade>
          <aliquota>17.0</aliquota>
          <valor>550.1</valor>
        </impostos>
      </impostos>
      <papel>ub22</papel>
      <valor>30.62</valor>
      <quantidade>150.0</quantidade>
      <data>2020-01-29 20:55:51.485 UTC</data>
    </operacao>
  </compras>
</balanco>

Segue classes:

public class XStreamBalancoTester {

public static String vendaVazia;

@XStreamImplicit(itemFieldName = "list")
static ArrayList<Object> objectList = new ArrayList<Object>();

static ArrayList<Object> balancos = new ArrayList<Object>();
static XStreamBalancoTester tester = new XStreamBalancoTester();
static Balanco balancoP = new Balanco();
static Operacao operacaoP = new Operacao();
static Imposto impostos = new Imposto();
static ArrayList<Balanco> listaBalancosParam = new ArrayList<Balanco>();

static Balanco balancoTester = new Balanco();
static Balanco balancoTesterGet = new Balanco();

public static void main(String[] args) {

/*
* Serialização metodo lista
*/
XStream xstream = new XStream(new DomDriver()); // Stax imprime em linha unica com cabeçalho
xstream.autodetectAnnotations(true); // ou
// xstream.alias("balanco", Balanco.class);
// xstream.alias("operacao", Operacao.class);
xstream.setMode(XStream.NO_REFERENCES);

balancos = tester.getBalancos(2, objectList, balancoP, operacaoP, xstream, impostos);
if (!vendaVazia.isEmpty()) {
xstream.omitField(Balanco.class, "vendas");
}
// xstream.addImplicitCollection(Balanco.class, "vendas");

String xml = xstream.toXML(balancos);
System.out.println("getBalancos\n" + xml + "\n");



/*
* Exemplo 02 Serialização metodo lista
*/
XStream xstream2 = new XStream(new DomDriver()); // Stax imprime em linha unica com cabeçalho
xstream2.autodetectAnnotations(true);
xstream2.setMode(XStream.NO_REFERENCES);
balancoTester = balancoTesterGet.getListaBalancos(2, impostos, listaBalancosParam, balancoP, operacaoP,
xstream2);
String xml2 = xstream2.toXML(balancoTester);
System.out.println("getListaBalancos \n" + xml2 + "\n");		

}

private ArrayList<Object> getBalancos(int contador, ArrayList<Object> objectList, Balanco balanco,
Operacao operacao, XStream xstream, Imposto impostos) {

boolean temImposto = true;
int contadorr = 1;

while (contadorr <= contador) {

balanco = new Balanco();
balanco.setId(contadorr);
operacao = new Operacao();
operacao.setPapel("ub22");
operacao.setQuantidade(150);
operacao.setValor(30.62);
Calendar c1 = Calendar.getInstance();
operacao.setData(c1.getTime());

if (temImposto == true) {			
impostos = new Imposto(); 
impostos.setDescricao("ICMS");
impostos.setCidade("Joinville"); 
impostos.setEstado("Santa Catarina");
impostos.setAliquota(22.0); 
impostos.setValor(324.10);
operacao.addImpostos(impostos);
}

balanco.addCompra(operacao);

contadorr++;

}
if (balanco.getVendas().size() == 0) {
vendaVazia = "vazio";
} else {
vendaVazia = null;
}
if (operacao.getImpostos().size() == 0) {
xstream.omitField(Operacao.class, "impostos");
// xstream.addImplicitCollection(Operacao.class, "impostos");
}
objectList.add(balanco);
return objectList;

}

public static String formatXml(String xml) {

try {

Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

Source xmlSource = new SAXSource(new InputSource(new ByteArrayInputStream(xml.getBytes())));
StreamResult res = new StreamResult(new ByteArrayOutputStream());

serializer.transform(xmlSource, res);

return new String(((ByteArrayOutputStream) res.getOutputStream()).toByteArray());

} catch (Exception e) {
return xml;
}
}
}

public class XStreamAttributeTester {

public static void main(String[] args) {

String jSonComAtributo = "[{\"@id\":\"1\",\"rollNo\":1,\"firstName\":\"Mahesh\",\"lastName\":\"Parashar\",\"className\":\"1st\",\"address\":{\"area\":\"H.No. 16/3, Preet Vihar.\",\"city\":\"Delhi\",\"state\":\"Delhi\",\"country\":\"India\",\"pincode\":110012}},{\"@id\":\"2\",\"rollNo\":2,\"firstName\":\"Mahesh\",\"lastName\":\"Parashar\",\"className\":\"1st\",\"address\":{\"area\":\"H.No. 16/3, Preet Vihar.\",\"city\":\"Delhi\",\"state\":\"Delhi\",\"country\":\"India\",\"pincode\":110012}},{\"@id\":\"3\",\"rollNo\":3,\"firstName\":\"Mahesh\",\"lastName\":\"Parashar\",\"className\":\"1st\",\"address\":{\"area\":\"H.No. 16/3, Preet Vihar.\",\"city\":\"Delhi\",\"state\":\"Delhi\",\"country\":\"India\",\"pincode\":110012}}]";
String jSonSemAtributo = "[{\"rollNo\":1,\"id\":1,\"firstName\":\"Mahesh\",\"lastName\":\"Parashar\",\"className\":\"1st\",\"address\":{\"area\":\"H.No. 16/3, Preet Vihar.\",\"city\":\"Delhi\",\"state\":\"Delhi\",\"country\":\"India\",\"pincode\":110012}},{\"rollNo\":2,\"id\":2,\"firstName\":\"Mahesh\",\"lastName\":\"Parashar\",\"className\":\"1st\",\"address\":{\"area\":\"H.No. 16/3, Preet Vihar.\",\"city\":\"Delhi\",\"state\":\"Delhi\",\"country\":\"India\",\"pincode\":110012}},{\"rollNo\":3,\"id\":3,\"firstName\":\"Mahesh\",\"lastName\":\"Parashar\",\"className\":\"1st\",\"address\":{\"area\":\"H.No. 16/3, Preet Vihar.\",\"city\":\"Delhi\",\"state\":\"Delhi\",\"country\":\"India\",\"pincode\":110012}}]";

/*XStream xStreamJson = new XStream(new DomDriver());	
xStreamJson.alias("Student", Student.class);
// xStreamJson.aliasField("id", Student.class, "studentId");
xStreamJson.aliasField("rollNo", Student.class, "rollNo");
Student studentJson = (Student)xStreamJson.fromXML(jSonSemAtributo);
System.out.println(studentJson.getRollNo());*/

String jSon = "{\"product\":{\"name\":\"Banana\",\"id\":123"
+ ",\"price\":23.0}}";

String jSon2 = "{\r\n" + 
"    \"@id\": \"1\",\r\n" + 
"    \"rollNo\": 1,\r\n" + 
"    \"firstName\": \"Mahesh\",\r\n" + 
"    \"lastName\": \"Parashar\",\r\n" + 
"    \"className\": \"1st\",\r\n" + 
"    \"address\": {\r\n" + 
"      \"area\": \"H.No. 16/3, Preet Vihar.\",\r\n" + 
"      \"city\": \"Delhi\",\r\n" + 
"      \"state\": \"Delhi\",\r\n" + 
"      \"country\": \"India\",\r\n" + 
"      \"pincode\": 110012\r\n" + 
"    }\r\n" + 
"  },\r\n" + 
"  {\r\n" + 
"    \"@id\": \"2\",\r\n" + 
"    \"rollNo\": 2,\r\n" + 
"    \"firstName\": \"Mahesh\",\r\n" + 
"    \"lastName\": \"Parashar\",\r\n" + 
"    \"className\": \"1st\",\r\n" + 
"    \"address\": {\r\n" + 
"      \"area\": \"H.No. 16/3, Preet Vihar.\",\r\n" + 
"      \"city\": \"Delhi\",\r\n" + 
"      \"state\": \"Delhi\",\r\n" + 
"      \"country\": \"India\",\r\n" + 
"      \"pincode\": 110012\r\n" + 
"    }\r\n" + 
"  },\r\n" + 
"  {\r\n" + 
"    \"@id\": \"3\",\r\n" + 
"    \"rollNo\": 3,\r\n" + 
"    \"firstName\": \"Mahesh\",\r\n" + 
"    \"lastName\": \"Parashar\",\r\n" + 
"    \"className\": \"1st\",\r\n" + 
"    \"address\": {\r\n" + 
"      \"area\": \"H.No. 16/3, Preet Vihar.\",\r\n" + 
"      \"city\": \"Delhi\",\r\n" + 
"      \"state\": \"Delhi\",\r\n" + 
"      \"country\": \"India\",\r\n" + 
"      \"pincode\": 110012\r\n" + 
"    }\r\n" + 
"  }";

String xml =  "<root>\r\n" + 
"  <element>\r\n" + 
"    <rollNo>1</rollNo>\r\n" + 
"    <id>1</id>\r\n" + 
"    <firstName>Mahesh</firstName>\r\n" + 
"    <lastName>Parashar</lastName>\r\n" + 
"    <className>1st</className>\r\n" + 
"    <address>\r\n" + 
"      <area>H.No. 16/3, Preet Vihar.</area>\r\n" + 
"      <city>Delhi</city>\r\n" + 
"      <state>Delhi</state>\r\n" + 
"      <country>India</country>\r\n" + 
"      <pincode>110012</pincode>\r\n" + 
"    </address>\r\n" + 
"  </element>\r\n" + 
"  <element>\r\n" + 
"    <rollNo>2</rollNo>\r\n" + 
"    <id>2</id>\r\n" + 
"    <firstName>Mahesh</firstName>\r\n" + 
"    <lastName>Parashar</lastName>\r\n" + 
"    <className>1st</className>\r\n" + 
"    <address>\r\n" + 
"      <area>H.No. 16/3, Preet Vihar.</area>\r\n" + 
"      <city>Delhi</city>\r\n" + 
"      <state>Delhi</state>\r\n" + 
"      <country>India</country>\r\n" + 
"      <pincode>110012</pincode>\r\n" + 
"    </address>\r\n" + 
"  </element>\r\n" + 
"  <element>\r\n" + 
"    <rollNo>3</rollNo>\r\n" + 
"    <id>3</id>\r\n" + 
"    <firstName>Mahesh</firstName>\r\n" + 
"    <lastName>Parashar</lastName>\r\n" + 
"    <className>1st</className>\r\n" + 
"    <address>\r\n" + 
"      <area>H.No. 16/3, Preet Vihar.</area>\r\n" + 
"      <city>Delhi</city>\r\n" + 
"      <state>Delhi</state>\r\n" + 
"      <country>India</country>\r\n" + 
"      <pincode>110012</pincode>\r\n" + 
"    </address>\r\n" + 
"  </element>\r\n" + 
"</root>";

String xml2 =  "<rollNo>1</rollNo>\r\n" + 
"    <id>1</id>\r\n" + 
"    <firstName>Mahesh</firstName>\r\n" + 
"    <lastName>Parashar</lastName>\r\n" + 
"    <className>1st</className>\r\n" + 
"    <address>\r\n" + 
"      <area>H.No. 16/3, Preet Vihar.</area>\r\n" + 
"      <city>Delhi</city>\r\n" + 
"      <state>Delhi</state>\r\n" + 
"      <country>India</country>\r\n" + 
"      <pincode>110012</pincode>\r\n" + 
"    </address>\r\n" +     	
"    <rollNo>2</rollNo>\r\n" + 
"    <id>2</id>\r\n" + 
"    <firstName>Mahesh</firstName>\r\n" + 
"    <lastName>Parashar</lastName>\r\n" + 
"    <className>1st</className>\r\n" + 
"    <address>\r\n" + 
"      <area>H.No. 16/4, Preet Vihar.</area>\r\n" + 
"      <city>LA</city>\r\n" + 
"      <state>LA</state>\r\n" + 
"      <country>India</country>\r\n" + 
"      <pincode>110012</pincode>\r\n" + 
"    </address>\r\n" +     	
"    <rollNo>3</rollNo>\r\n" + 
"    <id>3</id>\r\n" + 
"    <firstName>Mahesh</firstName>\r\n" + 
"    <lastName>Parashar</lastName>\r\n" + 
"    <className>1st</className>\r\n" + 
"    <address>\r\n" + 
"      <area>H.No. 16/5, Preet Vihar.</area>\r\n" + 
"      <city>Jl</city>\r\n" + 
"      <state>Jl</state>\r\n" + 
"      <country>India</country>\r\n" + 
"      <pincode>110012</pincode>\r\n" + 
"    </address>\r\n";


//Leitura JSON
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.alias("product", Product.class);
Product product = (Product)xstream.fromXML(jSon);
System.out.println(product.getName() + "\n");

//Leitura XML
XStream xstreamLeitura = new XStream(new StaxDriver());  
xstreamLeitura.alias("br.com.MavenProjectTests.Student", Student.class);
xstreamLeitura.alias("rollNo", Student.class);
xstreamLeitura.alias("id", Student.class);
xstreamLeitura.alias("root", Student.class);
xstreamLeitura.alias("element", Student.class);
xstreamLeitura.alias("firstName", Student.class);
xstreamLeitura.alias("lastName", Student.class);
xstreamLeitura.alias("className", Student.class);
xstreamLeitura.alias("address", Student.class);   
Student studentLeitura = (Student)xstreamLeitura.fromXML(xml2);

System.out.println(studentLeitura.getFirstName());

}
}

public class XSTreamJsonTester {

public static void main(String args[]) {

XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {

public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});

Student student3 = new Student();
student3.setFirstName("Josh");
student3.setLastName("Iorq");

xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("student", Student.class); // ou 
//xstream.autodetectAnnotations(true);

System.out.println(xstream.toXML(student3));
}

}

public class XStreamReadingTester {

public static void main(String[] args) {


String xml = "<loginpojos>\r\n" + 
"	<loginpojo>\r\n" + 
"		<propLabel>JH</propLabel>\r\n" + 
"		<propName>John</propName>\r\n" + 
"		<propValue>11234</propValue>\r\n" + 
"	</loginpojo>\r\n" + 
"	<loginpojo>\r\n" + 
"		<propLabel>KS</propLabel>\r\n" + 
"		<propName>Kasne</propName>\r\n" + 
"		<propValue>494423</propValue>\r\n" + 
"	</loginpojo>\r\n" + 
"</loginpojos>";		

// Desserialização

XStream xstream2 = new XStream(new DomDriver());
xstream2.autodetectAnnotations(true);
xstream2.alias("loginpojos",LoginPojos.class);
xstream2.alias("loginpojo",LoginPojo.class);        
xstream2.addImplicitCollection(LoginPojos.class, "loginpojos");

LoginPojos loginPojosList = (LoginPojos)xstream2.fromXML(xml);

List<LoginPojo> loginPojoList = loginPojosList.getLoginpojos();
for(LoginPojo newLogiPojo:loginPojoList){
// Print out the newPerson properties
System.out.println("Property Label: " + newLogiPojo.getPropLabel());
System.out.println("Property Name: " + newLogiPojo.getPropName());
System.out.println("Property Value: " + newLogiPojo.getPropValue());
}

String xml2 = "<balanco>\r\n" + 
"  <id>2</id>\r\n" + 
"  <compras>\r\n" + 
"    <operacao>\r\n" + 
"      <impostos>\r\n" + 
"        <imposto>\r\n" + 
"          <descricao>ICMS</descricao>\r\n" + 
"          <estado>Sao Paulo</estado>\r\n" + 
"          <cidade>Garulhos</cidade>\r\n" + 
"          <aliquota>17.0</aliquota>\r\n" + 
"          <valor>550.1</valor>\r\n" + 
"        </imposto>\r\n" + 
"      </impostos>\r\n" + 
"      <papel>ub22</papel>\r\n" + 
"      <valor>30.62</valor>\r\n" + 
"      <quantidade>150.0</quantidade>\r\n" + 
"      <data>2020-01-30 16:55:12.788 UTC</data>\r\n" + 
"    </operacao>\r\n" + 
"    <operacao>\r\n" + 
"      <impostos>\r\n" + 
"        <imposto>\r\n" + 
"          <descricao>ICMS</descricao>\r\n" + 
"          <estado>Sao Paulo</estado>\r\n" + 
"          <cidade>Garulhos</cidade>\r\n" + 
"          <aliquota>17.0</aliquota>\r\n" + 
"          <valor>550.1</valor>\r\n" + 
"        </imposto>\r\n" + 
"      </impostos>\r\n" + 
"      <papel>ub22</papel>\r\n" + 
"      <valor>30.62</valor>\r\n" + 
"      <quantidade>150.0</quantidade>\r\n" + 
"      <data>2020-01-30 16:55:12.789 UTC</data>\r\n" + 
"    </operacao>\r\n" + 
"  </compras>\r\n" + 
"</balanco>";

}
}

public class XStreamTester {

public static void main(String args[]) {

ArrayList<Object> objectList2 = new ArrayList<Object>();
XStreamTester tester = new XStreamTester();
XStream xstream = new XStream(new DomDriver()); //new DomDriver() vem sem cabecalho do ?xml, StaxDriver() com ?xml
xstream.autodetectAnnotations(true);
xstream.setMode(XStream.NO_REFERENCES); //ID_REFERENCES

//Direto para o JSon sem usar a biblioteca GSON
XStream xstreamJson = new XStream(new JsonHierarchicalStreamDriver() {

public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});	      

objectList2 = tester.getStudentDetails(3);	      

//Object to XML Conversion
//Serialize the Object to XML
//Use toXML() method to get the XML string representation of the object
String xml = xstream.toXML(objectList2);
System.out.println("xml do student:\n" +xml + "\n");	      


//Objeto para Json direto do XStream	         
xstreamJson.setMode(XStream.NO_REFERENCES);	
xstreamJson.useAttributeFor(Student.class, "id"); // Esse cara é o responsável pelo @ no id para json. para xml, mudar alias na classe    
System.out.println("json xStreamJson serialização\n" + xstreamJson.toXML(objectList2) + "\n");	      


//Object to Json version using GSON
Gson gson = new Gson();	      
String json = gson.toJson(objectList2);
System.out.println("json Gson: " + json + "\n ");	      


//De-serialize XML to Get the Object
//Use fromXML() method to get the object from the XML.
//XML to Object Conversion

}

private ArrayList<Object> getStudentDetails(int contador) {

Student student = null;
Address address = null;
ArrayList<Object> objectList = new  ArrayList<Object>();
int contadorr = 1;

while(contadorr <= contador) {		

System.out.println(contadorr + " " + contador);
student = new Student();
address = new Address();
student.setId(contadorr);
student.setFirstName("Mahesh");
student.setLastName("Parashar");
student.setRollNo(contadorr);
student.setClassName("1st");

address.setArea("H.No. 16/3, Preet Vihar.");
address.setCity("Delhi");
address.setState("Delhi");
address.setCountry("India");
address.setPincode(110012);
student.setAddress(address);
contadorr++;
objectList.add(student);	      
}
return objectList;
}

public static String formatXml(String xml) {

try {
Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();

serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

Source xmlSource = new SAXSource(new InputSource(
new ByteArrayInputStream(xml.getBytes())));
StreamResult res =  new StreamResult(new ByteArrayOutputStream());            

serializer.transform(xmlSource, res);

return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());

} catch(Exception e) {
return xml;
}
}

}

@XStreamAlias("balanco")
public class Balanco {

@XStreamAlias("id") 
//@XStreamAsAttribute //isso afeta somente para geração de xml. para json, usar useAttributeFor
private int id;		

@XStreamImplicit(itemFieldName="list")
public ArrayList<Balanco> listaBalancos = new ArrayList<Balanco>();	

@XStreamImplicit(itemFieldName="list")
public ArrayList<Balanco> listaBalancosParam = new ArrayList<Balanco>();

private List<Operacao> compras = new ArrayList<Operacao>();
private List<Operacao> vendas = new ArrayList<Operacao>();

public void addCompra(Operacao operacao) {
this.compras.add(operacao);
}
public void addVenda(Operacao operacao) {
this.vendas.add(operacao);
}
public List<Operacao> getCompras() {
return compras;
}
public List<Operacao> getVendas() {
return vendas;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}	

public Balanco getListaBalancos(int contador, Imposto impostos, ArrayList<Balanco> balancoList, Balanco balanco,
Operacao operacao, XStream xstream) {

balanco.setId(contador);
int contadorr = 1;

while (contadorr <= contador) {			

operacao = new Operacao();
operacao.setPapel("ub22");
operacao.setQuantidade(150);
operacao.setValor(30.62);
Calendar c1 = Calendar.getInstance();
operacao.setData(c1.getTime());			

impostos = new Imposto();
impostos.setDescricao("ICMS");
impostos.setCidade("Garulhos");
impostos.setEstado("Sao Paulo");
impostos.setAliquota(17.0);
impostos.setValor(550.10);
operacao.addImpostos(impostos);						
balanco.addCompra(operacao);			
contadorr++;
System.out.println(balanco.getId());		
}
if (balanco.getVendas().size() == 0) {
xstream.omitField(Balanco.class, "vendas");
}
if (operacao.getImpostos().size() == 0) {
xstream.omitField(Operacao.class, "impostos");
//xstream.addImplicitCollection(Operacao.class, "impostos");
}

balancoList.add(balanco);		
return balanco;
}

}

@XStreamAlias("operacao")
public class Operacao {

@XStreamAlias("impostos")
private List<Imposto> impostos = new ArrayList<Imposto>();

@XStreamAlias("papel")
private String papel;

@XStreamAlias("valor")
private double valor;

@XStreamAlias("quantidade")
private double quantidade;

@XStreamAlias("data")
private Date data;

public void addImpostos(Imposto impostos) {
this.impostos.add(impostos);
}		
public List<Imposto> getImpostos() {
return impostos;
}	
public void setImpostos(List<Imposto> impostos) {
this.impostos = impostos;
}		
public Date getData() {
return data;		
}
public void setData(Date date) {
this.data = date;
}
public String getPapel() {
return papel;
}
public void setPapel(String papel) {
this.papel = papel;
}
public double getValor() {
return valor;
}
public void setValor(double valor) {
this.valor = valor;
}
public double getQuantidade() {
return quantidade;
}
public void setQuantidade(double quantidade) {
this.quantidade = quantidade;
}

@Override
public String toString() {

StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append("\noperacao  ");
stringBuilder.append("\npapel: ");
stringBuilder.append(papel);
stringBuilder.append("\nvalor: ");
stringBuilder.append(valor);
stringBuilder.append("\nquantidade: ");
stringBuilder.append(quantidade);
stringBuilder.append("\ndata: ");
stringBuilder.append(data);	
stringBuilder.append("\n");

return stringBuilder.toString();
}

}

Eu não conheço a api.
Mas a classe deveria ter o apelido no singular:

E a lista de impostos deveria ter um alias no plural.

@XStreamAlias(“impostos”)

1 curtida

Eu esqueci de colocar a classe de Impostos. Bem lembrado!

@XStreamAlias("imposto")
public class Impostos {

@XStreamAlias("descricao")
private String descricao;

@XStreamAlias("estado")
private String estado;

@XStreamAlias("cidade")
private String cidade;

@XStreamAlias("aliquota")
private double aliquota;

@XStreamAlias("valor")
private double valor;

public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
public String getEstado() {
return estado;
}
public void setEstado(String estado) {
this.estado = estado;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public double getAliquota() {
return aliquota;
}
public void setAliquota(double aliquota) {
this.aliquota = aliquota;
}
public double getValor() {
return valor;
}
public void setValor(double valor) {
this.valor = valor;
}	

}

Eu ajustei como vc mencionou e agora está correto! Valeu!

@XStreamAlias("imposto")
public class Impostos {

@XStreamAlias("operacao")
public class Operacao {

@XStreamAlias("impostos")
private List<Impostos> impostos = new ArrayList<Impostos>();

XML sendo gerado corretamente agora:

<balanco>
<id>2</id>
<compras>
<operacao>
<impostos>
<imposto>
<descricao>ICMS</descricao>
<estado>Sao Paulo</estado>
<cidade>Garulhos</cidade>
<aliquota>17.0</aliquota>
<valor>550.1</valor>
</imposto>
</impostos>
<papel>ub22</papel>
<valor>30.62</valor>
<quantidade>150.0</quantidade>
<data>2020-01-30 11:59:56.772 UTC</data>
</operacao>
<operacao>
<impostos>
<imposto>
<descricao>ICMS</descricao>
<estado>Sao Paulo</estado>
<cidade>Garulhos</cidade>
<aliquota>17.0</aliquota>
<valor>550.1</valor>
</imposto>
</impostos>
<papel>ub22</papel>
<valor>30.62</valor>
<quantidade>150.0</quantidade>
<data>2020-01-30 11:59:56.772 UTC</data>
</operacao>
</compras>
</balanco>

O nome da classe deve ser Imposto e não impostos, a semântica importa.

1 curtida