3

Note, this is not a duplicate of another question I asked, "With MOXy and XPath, is it possible to unmarshal a list of attributes?" It's similar, but not the same.

I've got XML that looks like this:

<test>
  <items>
    <item type="cookie" brand="oreo">cookie</item>
    <item type="crackers" brand="ritz">crackers</item>
  </items>
</test>

This is similar to the xml in my earlier question except now there are two attributes per item instead of one.

In my class:

@XmlPath("items/item/@type")
@XmlAttribute
private ArrayList<String> itemList = new ArrayList<String>();
@XmlPath("items/item/@brand")
@XmlAttribute
private ArrayList<String> brandList = new ArrayList<String>();

Thanks to the answer to my previous question I am able to unmarshal the type attribute into the list. brandList, however, is empty. If I comment out annotations for itemList (so it is not populated by JAXB/MOXy) then brandList contains the correct values.

It appears that I can only unmarshal a single attribute into a list using XPath. Is this by design or have I configured something wrong?

Update: It seems I can't unmarshal the text and an attribute from an element either. If my class is mapped like this:

@XmlPath("items/item/text()")
@XmlElement
private ArrayList<String> itemList = new ArrayList<String>();
@XmlPath("items/item/@brand")
@XmlAttribute
private ArrayList<String> brandList = new ArrayList<String>();

brandList is also empty in this case. If I switch the order and map brandList first then itemList is empty. It's as if the first mapping consumes the element so further values based on that element or its attributes cannot be read.

Community
  • 1
  • 1
Paul
  • 19,704
  • 14
  • 78
  • 96
  • Do you have the latest version of Moxy? I encountered some bugs with XPath attribute filtering using an older version (that disappeared when updating to the latest release). – Thilo Aug 18 '11 at 01:45
  • I have whatever came with EclipseLink 2.3, downloaded a couple of weeks ago. v2.3 seems to be the latest according to their download page. – Paul Aug 18 '11 at 01:55
  • That configuration currently won't give you the output that you are looking for. I will try to put together an alternative that you can use. Note: I'm the EclipseLink JAXB (MOXy) lead. – bdoughan Aug 18 '11 at 13:53
  • @Blaise, thank you. Since I can tweak my schema I just adjusted it so `item` has a nested element `brand` and it works fine. I'm sure you're very busy so please don't put anything aside for this. If you post an answer saying, "you can't do that" I'll accept it. – Paul Aug 18 '11 at 22:17
  • @Blaise, I've updated my question a little. It doesn't work on an attribute and the text of an element either. – Paul Aug 19 '11 at 02:41
  • Hi, I am trying to unmarshal my `XML` elements by referring to some of the answers and blogs but I am facing some problem. Here is the issue:I am trying to unmarshal the `XML` using `Moxy @XmlPath` but for some reason, I am unable to get the values for some fields. I have made a post for the same. If you get a chance, can you please have a look and provide your suggestion or workarounds? https://stackoverflow.com/questions/67648941/jaxb-moxy-unmarshalling-assigns-all-field-values-to-mapstring-object-rather-th – BATMAN_2008 May 23 '21 at 11:09

1 Answers1

3

Short Answer

This isn't a use case that is currently supported with @XmlPath in EclipseLink MOXy. I have entered the following enhancement request for this, feel free to add additional information to to vote for this bug:

Long Answer

MOXy will support mapping:

@XmlPath("items/item/@type")
private ArrayList<String> itemList = new ArrayList<String>();

to:

<test>
  <items>
    <item type="cookie"/>
    <item type="crackers"/>
  </items>
</test>

but not:

@XmlPath("items/item/@type")
private ArrayList<String> itemList = new ArrayList<String>();

@XmlPath("items/item/@brand")
private ArrayList<String> brandList = new ArrayList<String>();

to:

<test>
  <items>
    <item type="cookie" brand="oreo"/>
    <item type="crackers" brand="ritz"/>
  </items>
</test>

Workaround

You could introduce an intermediate object (Item) to map this use case:

@XmlElementWrapper(name="items")
@XmlElement(name="item")
private ArrayList<Item> itemList = new ArrayList<Item>();

 

public class Item {

    @XmlAttribute
    private String type;

    @XmlAttribute
    private String brand;
}

For More Information on @XmlPath

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Thanks so much! Do you know of a good resource where I can learn how and when to use `@XmlAttribute`, `@XmlElement`, etc? I haven't noticed a difference if I accidentally swap one for the other, or even if I leave them out when using `@XmlPath`. – Paul Aug 19 '11 at 14:55
  • 1
    @Paul - Not sure of a specific resource I can point you at. If you are using `@XmlPath` then you do not need to use `@XmlAttribute` or `@XmlElement`. Also annotating fields or properties is important, the following may help: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html. – bdoughan Aug 19 '11 at 15:07
  • Isn't the use case still supported? I need some xml elements in a java class to be under the same grouping. I am using xpath for adding the grouping tag. But how can i bring multiple elments under the same subtag? – Aparna Jul 28 '16 at 09:09