当前位置: 首页 > 面试题库 >

Java / JAXB:将XML属性解组为特定的Java对象属性

农存
2023-03-14
问题内容

有一个丑陋的XML文件必须解组:

<?xml version="1.0" ?>
<configuration>
    <section name="default_options">
        <value name="default_port">8081</value>
        <value name="log_level">WARNING</value>
    </section>
    <section name="custom_options">
        <value name="memory">64M</value>
        <value name="compatibility">yes</value>
    </section>
</configuration>

产生的Java对象应为:

public class DefaultOptions {
    private int defaultPort;
    private String logLevel;
    // etc...
}

public class CustomOptions {
    private String memory;
    private String compatibility;
    // etc...
}

这个问题的答案非常接近,但我不知道最终的解决方案。


问题答案:

怎么样?

介绍一个称为选项的通用超类:

import javax.xml.bind.annotation.XmlAttribute;

public abstract class Options {

    private String name;

    @XmlAttribute
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

然后在带有选项列表的类(在本示例中为Configuration)上,在该属性上指定一个@XmlJavaTypeAdapter:

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Configuration {

    private List<Options> section = new ArrayList<Options>();

    @XmlJavaTypeAdapter(OptionsAdapter.class)
    public List<Options> getSection() {
        return section;
    }

    public void setSection(List<Options> section) {
        this.section = section;
    }

}

XmlAdapter看起来像这样:

import javax.xml.bind.annotation.adapters.XmlAdapter;

public class OptionsAdapter extends XmlAdapter<AdaptedOptions, Options> {

    @Override
    public Options unmarshal(AdaptedOptions v) throws Exception {
        if("default_options".equals(v.name)) {
            DefaultOptions options = new DefaultOptions();
            options.setName(v.getName());
            options.setDefaultPort(Integer.valueOf(v.map.get("default_port")));
            options.setLogLevel(v.map.get("log_level"));
            return options;
        } else {
            CustomOptions options = new CustomOptions();
            options.setName(v.getName());
            options.setCompatibility(v.map.get("compatibility"));
            options.setMemory(v.map.get("memory"));
            return options;
        }
    }

    @Override
    public AdaptedOptions marshal(Options v) throws Exception {
        AdaptedOptions adaptedOptions = new AdaptedOptions();
        adaptedOptions.setName(v.getName());
        if(DefaultOptions.class == v.getClass()) {
            DefaultOptions options = (DefaultOptions) v;
            adaptedOptions.map.put("default_port", String.valueOf(options.getDefaultPort()));
            adaptedOptions.map.put("log_level", options.getLogLevel());
        } else {
            CustomOptions options = (CustomOptions) v;
            adaptedOptions.map.put("compatibility", options.getCompatibility());
            adaptedOptions.map.put("memory", options.getMemory());
        }
        return adaptedOptions;
    }

}

AdaptedOptions看起来像:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlValue;

public class AdaptedOptions extends Options {

    @XmlAttribute String name;
    @XmlElement List<Value> value = new ArrayList<Value>();
    Map<String, String> map = new HashMap<String, String>();

    public void beforeMarshal(Marshaller marshaller) {
        for(Entry<String, String> entry : map.entrySet()) {
            Value aValue = new Value();
            aValue.name = entry.getKey();
            aValue.value = entry.getValue();
            value.add(aValue);
        }
    }

    public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
        for(Value aValue : value) {
            map.put(aValue.name, aValue.value);
        }
    }

    private static class Value {
        @XmlAttribute String name;
        @XmlValue String value;
    }

}


 类似资料:
  • 问题内容: 是否可以使用JAXB根据xml的属性将xml解组到特定的Java类? 我想要一个包含三角形和正方形的Shape对象的列表,每个对象都有自己的特定于形状的属性。IE浏览器: 我目前只是将所有属性都放在一个大的“ Shape”类中,这并不理想。 如果形状已正确命名为xml元素,则可以使它正常工作,但是不幸的是,我无法控制要检索的xml。 谢谢! 问题答案: JAXB是一个规范,特定的实现将

  • 我还有这个包含ID列表: 我想筛选以便筛选的不包含id来自的对象,因此我尝试使用stream: 我找不到做这件事的正确函数。有人有什么建议让我试试吗?

  • 我有一个来自REST API的XML响应,如下所示: 我知道如何使用jaxb获取xml元素值,即“XYZ”,并绑定到bean。但我被困在知道如何获取资源的价值(即https://www.cyz.com),单位(“PH”),href(“ww.com”),div?内xmlns的值,然后将该值映射到对象属性。请帮助我。

  • 我试图将我下面的xml转换为java对象。 这是我的xml: 我需要在"提供者组织"下获取"name"的值。下面是我Java课。 诊所ocument.java 记录目标。JAVA 病人ole.java 供应商组织。JAVA XMLFileParserSAXUtility.java 我得到的结果是 如果我尝试打印syso(临床文件); 结果是临床文档[recordTarget=null] 请帮帮我!

  • 问题内容: 我需要使用特定对象的属性(位置)对对象(学生)列表进行分组,代码如下所示, 请给我建议一个干净的方法。 问题答案: In Java 8:

  • 问题内容: 有没有一种方法可以通过杰克逊将xml(例如int)序列化为xml属性?我找不到任何特别的杰克逊或json批注(@XmlAttribute @ javax.xml.bind.annotation.XmlAttribute)来实现此目的。 例如 我想要的是: 但是我得到的是: 有没有一种方法来获取属性而不是元素?感谢帮助! 问题答案: 好吧,我找到了解决方案。 如果您使用jackson-d