Page 1 of 1

JAXB/Moxy @XmlPath(".") conflicts with the XMLAdapter during

PostPosted: Tue Jun 08, 2021 5:24 am
by BATMAN_2008
Was unable to find the solution even after trying many things so posting here hoping to get some workaround or fix for this issue.

In short, I would like to perform the `unmarshalling` as mentioned here: http://blog.bdoughan.com/2013/06/moxys-xmlvariablenode-using-maps-key-as.html but along with Map I will have one more @XmlElement. So one field is annotated with (Map field) @XmlPath(".") and another field with (String field) @XmlElement and then I would like to perform unmarshalling.

Basically, if the @XmlPath(".") has been used on a Map and if there is XMLAdapter on it then it fails during the unmarshalling. The marshaling works perfectly only the unmarshalling fails. All I would like to know is how to read the custom or user-defined elements using the @XmlPath(".") and XMLAdapter. During the unmarshalling I get the NULL values if I use both of them. I am sure there should be some way but at present nothing is working for me.

Following is the XML that I am trying to unmarshal:
Code: Select all
<Customer xmlns:google="[url]https://google.com[/url]">
  <name>Batman</name>
  <age>2008</age>
  <google:sub1>MyValue-1</google:sub1>
  <google:sub2>MyValue-1</google:sub2>
</Customer>


Following is the Customer.class to which it will be unmarshalled:
Code: Select all
@XmlRootElement(name = "Customer")
@XmlType(name = "Customer", propOrder = {"name", "age", "userExtensions"})
@XmlAccessorType(XmlAccessType.FIELD)
@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
public class Customer extends Person {

  private String name;
  private String age;

  @XmlPath(".")
  @XmlJavaTypeAdapter(TestAdapter.class)
  @XmlAnyElement
  private Map<String, Object> userExtensions = new HashMap<>();
}


Following is the Main class which will unmarshal:
Code: Select all
public class Unmarshalling {
  public static void main(String[] args)
      throws JAXBException, XMLStreamException, FactoryConfigurationError, IOException, URISyntaxException, ProcessingException {
    final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("customer.xml");
    final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
    final JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
    final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    final Customer customer = unmarshaller.unmarshal(xmlStreamReader, Customer.class).getValue();
    System.out.println("Read XML : " + customer);
  }
}


When I run this code I will get the output as:
Code: Select all
Read XML : Person(name=Rise Against, age=2000)


It's not reading the `custom or user-defined` elements such as google:sub1 and google:sub2.

1. There is one more issue similar to this https://stackoverflow.com/questions/27765087/xmlpath-conflicts-with-xmladapter but the workaround mentioned there did not work for me.
2. I tried the @XmlAnyElement(lax=true) on MAP even that did not work for me.

Following is the TestAdapter that I am using for marshaling and unmarshalling the Map<String,Object>
Code: Select all
public class TestAdapter extends XmlAdapter<Wrapper, Map<String, Object>> {

  @Override
  public Map<String, Object> unmarshal(Wrapper value) throws Exception {
    System.out.println("ADAPTER UNMARSHALLING");
    System.out.println(value.getElements());

    if (value == null) {
      return null;
    }

    //Loop across all elements within ILMD tag
    final Map<String, Object> extensions = new HashMap<>();
    for (Object obj : value.getElements()) {
      Element element = (Element) obj;

      //System.out.println("Node Name : " + element.getNodeName() + " Value : " + element.getTextContent());

      final NodeList children = element.getChildNodes();

      if (children.getLength() == 1) {
        extensions.put(element.getNodeName(), element.getTextContent());
      } else {
        List<Object> child = new ArrayList<>();
        for (int i = 0; i < children.getLength(); i++) {
          final Node n = children.item(i);
          if (n.getNodeType() == Node.ELEMENT_NODE) {
            Wrapper wrapper = new Wrapper();
            List childElements = new ArrayList();
            childElements.add(n);
            wrapper.elements = childElements;
            child.add(unmarshal(wrapper));
          }
        }
        extensions.put(element.getNodeName(), child);
      }
    }
    return extensions;
  }

  @SuppressWarnings("unchecked")
  @Override
  public Wrapper marshal(Map<String, Object> v) throws Exception {
    if (v == null) {
      return null;
    }

    Wrapper wrapper = new Wrapper();
    List elements = new ArrayList();
    for (Map.Entry<String, Object> property : v.entrySet()) {
      if (property.getValue() instanceof Map) {
        elements.add(new JAXBElement<Wrapper>(new QName(property.getKey()), Wrapper.class, marshal((Map) property.getValue())));
      } else {
        elements.add(new JAXBElement<String>(new QName(property.getKey()), String.class, property.getValue().toString()));
      }
    }
    wrapper.elements = elements;
    return wrapper;
  }
}

class Wrapper {

  @XmlAnyElement
  List elements;

  public List getElements() {
    return elements;
  }


I tried many things but nothing worked till now. Can someone please have a look at this issue and provide your solution. Happy to provide any more info with regards to this issue as I have spent nearly 10 days looking for answers.

There is an open ticket with regards to this issuehttps://bugs.eclipse.org/bugs/show_bug.cgi?id=457169. I tried the solution mentioned there but still, my XML is not read properly. Kindly provide some solutions.

I tried the following things:
1. Created one more variable and tried to use it only during unmarshalling but that's also failing.
2. Tried to create one more field then used the `@XmlAnyElement` on it but that's also not working as I expected.

Everything is failing. I tried to debug the code from `MOXY` but I am unable to follow many things there. Any help with this issue would be really helpful for me.


[1]: https://stackoverflow.com/q/27765087/7584240
[2] https://bugs.eclipse.org/bugs/show_bug.cgi?id=457169

Re: JAXB/Moxy @XmlPath(".") conflicts with the XMLAdapter du

PostPosted: Wed Jun 16, 2021 7:24 pm
by jason
I'm afraid you won't get any help on this here.

Do you have to use MOXy? If so, have you tried posting to https://www.eclipse.org/forums/index.ph ... frm_id=111

If not, you could try using https://github.com/eclipse-ee4j/jaxb-ri which is quite active