title: XStream - Challenge adding attribute to child element
body: <p>I am having difficulty adding an attribute to a child element for writing an XML file. The challenge, for me at least, is that the POJO that the element is mapped to is associated with a parent element. I want the XML output to look like this:</p>
  
  <pre><code>&lt;TXLife version="2.42.00" xmlns="http://ACORD.org/Standards/Life/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
    &lt;TXLifeRequest&gt;
      &lt;TransRefGUID&gt;906D67C1-CC4D-11CF-91FB-444554540000&lt;/TransRefGUID&gt;
      &lt;TransType tc="1203"&gt;&lt;/TransType&gt;
      &lt;TransExeDate&gt;2020-01-06&lt;/TransExeDate&gt;
      &lt;TransExeTime&gt;09:30:00&lt;/TransExeTime&gt;
      ...multiple other parent and child elements..
    &lt;/TXLifeRequest&gt;
  &lt;/TXLife&gt;
  </code></pre>
  
  <p>It's the <strong>TransType</strong> element in which I need to add the attribute (as shown above). </p>
  
  <p>The POJOS:</p>
  
  <pre><code>@XStreamAlias("TXLife")
  public class TXLife {
  
      @XStreamAsAttribute
      private String version;
  
      @XStreamAsAttribute
      final String xmlns = "http://ACORD.org/Standards/Life/2";
  
      @XStreamAsAttribute
      @XStreamAlias("xmlns:xsi")
      final String xlink="http://www.w3.org/2001/XMLSchema-instance";
  
      @XStreamImplicit
      private List&lt;TXLifeRequest&gt; transListings = new ArrayList&lt;TXLifeRequest&gt;();
  
      public TXLife() {
          super();
      }
  ...getters and setters
  </code></pre>
  
  <pre><code>@XStreamAlias("TXLifeRequest")
  public class TXLifeRequest {
  
      @XStreamAlias("TransRefGUID")
      private String transRefGUID;
  
      @XStreamAlias("TransType")
      private String transType;
  
      @XStreamAlias("TransExeDate")
      private String transExeDate;
  
      @XStreamAlias("TransExeTime")
      private String transExeTime;
  
      public TXLifeRequest(String transRefGUID, String transType, String transExeDate, String transExeTime) {
          this.transRefGUID = transRefGUID;
          this.transType = transType;
          this.transExeDate = transExeDate;
          this.transExeTime = transExeTime;
      }
  ...getters and setters
  </code></pre>
  
  <p>Converter:</p>
  
  <pre><code>public class TransTypeAttributeConverter implements Converter {
  
      @Override
      public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
          TXLifeRequest txLifeRequest = (TXLifeRequest) o;
          hierarchicalStreamWriter.addAttribute("tc", "1203");
          hierarchicalStreamWriter.setValue("");
      }
  
      @Override
      public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
          return null;
      }
  
      @Override
      public boolean canConvert(Class type) {
          return type.equals(TXLifeRequest.class);
      }
  }
  </code></pre>
  
  <p>Test class:</p>
  
  <pre><code>public class TestXMLOutput {
  
      public static void main(String[] args) throws UnsupportedEncodingException {
  
          TestXMLOutput testXMLOutput = new TestXMLOutput();
  
          TXLife txLife = new TXLife();
          txLife.setVersion("2.42.00");
          txLife.add(new TXLifeRequest("906D67C1-CC4D-11CF-91FB-444554540000", "",
                  "2020-01-06", "09:30:00"));
  
          testXMLOutput.testConvertAndWriteXMLToFile(txLife);
  
      }
  
      public void testConvertAndWriteXMLToFile(TXLife txLife) throws UnsupportedEncodingException {
          XStream xstream = new XStream(new StaxDriver());
          xstream.processAnnotations(TXLife.class);
          xstream.alias("TXLife", TXLife.class);
          xstream.processAnnotations(TXLifeRequest.class);
          xstream.alias("TXLifeRequest", TXLifeRequest.class);
  
          BufferedOutputStream bos = null;
          try {
              bos = new BufferedOutputStream(new FileOutputStream("CITS_BoB/src/test/java/txlife.xml"));
          } catch (IOException e) {
              System.out.println("IOException Occurred: " + e.getMessage());
          }
  
          xstream.addImplicitCollection(TXLife.class, "transListings");
          //xstream.registerConverter(new TransTypeAttributeConverter());
  
          xstream.marshal(txLife, new PrettyPrintWriter(
                  new OutputStreamWriter(bos, StandardCharsets.UTF_8)));
  
  
      }
  }
  </code></pre>
  
  <p>I have found that running both the <em>xstream.addImplicitCollection(...)</em> and <em>xstream.registerConverter(...)</em> in the test class produces the following XML output:</p>
  
  <pre><code>&lt;TXLife version="2.42.00" xmlns="http://ACORD.org/Standards/Life/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
    &lt;TXLifeRequest tc="1203"&gt;&lt;/TXLifeRequest&gt;
  &lt;/TXLife&gt;
  </code></pre>
  
  <p>I am sure I have misunderstood, or missed altogether, how to properly use xstream to do this sort of task. In any examples I have found online the element to which the attribute is added is mapped to a class, whereas in my case the element I want to add the attribute to is itself in a class that is mapped to a "parent" element. I have gone through the <a href="https://x-stream.github.io/" rel="nofollow noreferrer">xstream</a> website but haven't found any example directly related to my goal here. JAXB is unfortunately not an option as I am using openjdk 12 which does not support that. I don't know if there is an XML document writer built into openjdk 12 (I am still new to that version). I guess what I can't figure out is how to somehow "associate" the specific child element in the TXLifeRequest POJO with the attribute I want added to it. Please excuse my incorrect use of code, for one, the string literals added in the <em>hierarchicalStreamWriter.addAttribute("tc", "1203");</em> statement in the <strong>TransTypeAttributeConverter</strong> I am sure are in the wrong context or place. If anyone can shed some light on this it would be greatly appreciated. Thank you!</p>
  
  <p>Sorry, I should also add that other options I have considered is to write POJOs for each element (which I realize is likely extreme and inefficient), or, to map the child element in the POJO to an inner class such that it in effect becomes it's own <em>parent</em> element.</p>