Domanda

I'm using Castor to write out a map of user ID's to time intervals. I'm using it to save and resume progress in a lengthy task, and I'm trying to make the XML as compact as possible. My map is from string userID's to a class that contains the interval timestamps, along with additional transient data that I don't need to serialize.

I'm able to use a nested class mapping:

...
<field name="userIntervals" collection="map">
 <bind-xml name="u">
  <class name="org.exolab.castor.mapping.MapItem">
   <field name="key" type="string"><bind-xml name="n" node="attribute"/></field>
   <field name="value" type="my.package.TimeInterval"/>
  </class>
 </bind-xml>
</field>
...
<class name="my.package.TimeInterval">
 <map-to xml="ti"/>
 <field name="intervalStart" type="long"><bind-xml name="s" node="attribute"/></field>
 <field name="intervalEnd" type="long"><bind-xml name="e" node="attribute"/></field>
</class>
...

And get output that looks like:

<u n="36164639"><value s="1292750896000" e="1292750896000"/></u>

What I'd like is the name, start, and end of the user in a single node like this.

<u n="36164639" s="1292750896000" e="1292750896000"/>

But I can't seem to finagle it so the start and end attributes in the "value" go in the same node as the "key". Any ideas would be greatly appreciated.

È stato utile?

Soluzione 3

Am answering my own question here, since there is a solution that does exactly what I want, and there's actually an error in the explanation at http://www.castor.org/xml-mapping.html#Sample-3:-Using-the-container-attribute - the container attribute is exactly what's needed here.

Changing one line in the mapping:

<field name="value" type="my.package.TimeInterval" container="true"/>

did exactly what I wanted, it didn't create a subelement for the value, just mapped the fields into the existing parent element. Since then, I've used this quite a few times to map multiple-value classes into their parent.

The error of course is the documentation states you do this by setting the container attribute to false. Of course, it should be true.

Altri suggerimenti

Nash, I think to arrange the castor mapping is bit tricky. If you want to have structure like

<u n="36164639" s="1292750896000" e="1292750896000"/> 

Then you need to create a new pojo file where it will be having all the three fields Key,intervalStart,intervalEnd. And let the File name as KeyTimeInterval And map it like the below.

 <field name="userIntervals" collection="map">    
  <class name="org.exolab.castor.mapping.MapItem">   
    <field name="u" type="my.package.KeyTimeInterval">
      <bind-xml name="u" node="element"/>
    </field>             
   </class>        
 </field>



<class name="my.package.KeyTimeInterval">  
  <field name="key" type="String">
        <bind-xml name="n" node="attribute"/></field> 
    <field name="intervalStart" type="long">
        <bind-xml name="s" node="attribute"/></field>   
     <field name="intervalEnd" type="long">
      <bind-xml name="e" node="attribute"/></field>   
 </class> 

I think you should be able to use location on s and e. Try this:-

...

<class name="my.package.TimeInterval">
   <map-to xml="ti"/>
   <field name="intervalStart" type="long">
      <bind-xml name="s" location="u" node="attribute"/>
   </field>
   <field name="intervalEnd" type="long">
      <bind-xml name="e" location="u" node="attribute"/>
   </field>
</class>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top