有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用JAXB将XML解析为不同的数据结构

我正在开发一个查询Eve Central的工具。Eve中心查询以XML格式返回,如下所示:

<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>

我想使用注释将此格式解析为以下数据类:

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;

    ....
}

现在,MarketStatObjectStats对象的注释应该是不言自明的,但我已经了解了“type”的XML结构,它是buy/sell/all统计数据的包装器

解决这个问题的最佳方法是什么?我不希望类型id是一个列表,因为这完全没有必要


共 (2) 个答案

  1. # 1 楼答案

    @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;
    }
    
  2. # 2 楼答案

    注意:我是EclipseLink JAXB (MOXy)领导和JAXB (JSR-222)专家组成员

    对于这个用例,您可以使用MOXy的@XmlPath扩展:

    MarketStatoObject

    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;
    
    }
    

    演示

    标准JAXB运行时API用于将XML与对象进行转换

    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);
        }
    
    }
    

    了解更多信息