简体   繁体   中英

Parse XML to different data structure with JAXB

I'm working on a tool to query Eve-Central. Eve-Central queries are returned in XML format, as such:

<evec_api version="2.0" method="marketstat_xml">
    <marketstat>
        <type id="608">
            <buy>
                <volume>74018</volume>
                <avg>68274.08</avg>
                <max>410000.01</max>
                <min>25000.23</min>
                <stddev>97055.39</stddev>
                <median>50000.00</median>
                <percentile>255537.71</percentile>
            </buy>
            <sell>
                <volume>15324</volume>
                <avg>477255.37</avg>
                <max>1914490.39</max>
                <min>175000.00</min>
                <stddev>266422.73</stddev>
                <median>407994.99</median>
                <percentile>309282.09</percentile>
            </sell>
            <all>
                <volume>87592</volume>
                <avg>107228.56</avg>
                <max>486000.00</max>
                <min>10.00</min>
                <stddev>123725.64</stddev>
                <median>50000.00</median>
                <percentile>47814.35</percentile>
            </all>
        </type>
    </marketstat>
</evec_api>

I would like to parse this format into the following data class using annotations:

public class MarketStatObject {

    private int id;
    private MarketStatObjectStats buy;
    private MarketStatObjectStats sell;
    private MarketStatObjectStats all;

    ....
}

public class MarketStatObjectStats {

    // values
    private long volume;
    private double average;
    private double minimum;
    private double maximum;
    private double stddev;
    private double median;
    private double percentile;

    ....
}

Now, the annotations for the MarketStatObjectStats object should be quite self explanatory but I'm caught up with the XML structure of "type" being a wrapper for the buy/sell/all statistics.

What would be the best way to solve this? I don't want type id to be a list since that's totally unnecessary...

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

You could use MOXy's @XmlPath extension for this use case:

MarketStatObject

package forum17988539;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="evec_api")
@XmlAccessorType(XmlAccessType.FIELD)
public class MarketStatObject {

    @XmlPath("marketstat/type/@id")
    private int id;

    @XmlPath("marketstat/type/buy")
    private MarketStatObjectStats buy;

    @XmlPath("marketstat/type/sell")
    private MarketStatObjectStats sell;

    @XmlPath("marketstat/type/all")
    private MarketStatObjectStats all;

}

Demo

The standard JAXB runtime APIs are used to conversion your XML to/from Objects.

package forum17988539;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(MarketStatObject.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum17988539/input.xml");
        MarketStatObject marketStat = (MarketStatObject) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(marketStat, System.out);
    }

}

For More Information

@XmlRootElement(name = "evec_api")
public class EvecApi {
    @XmlElement MarketStat marketstat;
}

public class MarketStat {
    @XmlElement MarketStatObject type;
}

public class MarketStatObject {
    @XmlAttribute Integer id;
    @XmlElement MarketStatObjectStats buy;
    @XmlElement MarketStatObjectStats sell;
    @XmlElement MarketStatObjectStats all;
}

public class MarketStatObjectStats {
    @XmlElement long volume;
    @XmlElement double average;
    @XmlElement double minimum;
    @XmlElement double maximum;
    @XmlElement double stddev;
    @XmlElement double median;
    @XmlElement double percentile;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM