有 Java 编程相关的问题?

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

java使用JAXB解析基于属性的xml

我正在使用JAXB解析一些xml

<countries>
    <Name language="en">Australia</Name>
    <Name language="se">Australien</Name>
</countries>

如果我在我的班级使用

@XmlElement(name = "Name", required = true)
    protected List<Name> name;

一切正常。 然而,我只想得到language=“en”所在的属性

所以我在我的国家班上

protected String name

不是收藏

有没有一个很好的方法来解决这个问题,比如用一些注释


共 (1) 个答案

  1. # 1 楼答案

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

    下面是处理这个用例的两种方法。第一个是更多的代码,但可以通过任何JAXB实现来完成。第二个是更少的代码,但需要使用EclipseLink JAXB(MOXy)

    选项#1-任何JAXB(JSR-222)实现

    演示

    您可以使用过滤流读取器过滤掉不需要的元素,并让您的JAXB实现解组这些元素

    package forum11586106;
    
    import javax.xml.bind.*;
    import javax.xml.stream.*;
    import javax.xml.transform.stream.StreamSource;
    
    public class Demo {
    
        private static final String LANGUAGE_CODE = "en";
    
        public static void main(String[] args) throws Exception {
            XMLInputFactory xif = XMLInputFactory.newFactory();
            XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/forum11586106/input.xml"));
            xsr = xif.createFilteredReader(xsr, new StreamFilter() {
    
                private boolean isReading = true;
    
                @Override
                public boolean accept(XMLStreamReader reader) {
                    if(reader.isStartElement() && "Name".equals(reader.getLocalName())) {
                        isReading = LANGUAGE_CODE.equals(reader.getAttributeValue("", "language"));
                        return isReading;
                    } else if(reader.isEndElement() && !isReading) {
                        isReading = true;
                        return false;
                    }
    
                    return true;
                }});
    
            JAXBContext jc = JAXBContext.newInstance(Countries.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            Countries countries = (Countries) unmarshaller.unmarshal(xsr);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(countries, System.out);
        }
    
    }
    

    国家

    package forum11586106;
    
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
    public class Countries {
    
        private String name;
    
        @XmlElement(name="Name")
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    

    输入。xml

    使用这种方法,输出中不包括语言属性:

    <countries>
        <Name language="en">Australia</Name>
        <Name language="se">Australien</Name>
    </countries>
    

    输出

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <countries>
        <Name>Australia</Name>
    </countries>
    

    选项#2-ECLIPSELINK JAXB(MOXy)

    我们将利用MOXy的@XmlPath扩展来映射到Name元素,该元素有一个language属性,其值为en(请参见http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html

    国家

    package forum11586106;
    
    import javax.xml.bind.annotation.*;
    import org.eclipse.persistence.oxm.annotations.XmlPath;
    
    @XmlRootElement
    public class Countries {
    
        private String name;
    
        @XmlPath("Name[@language='en']/text()")
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    

    jaxb。属性

    要使用MOXy作为JAXB提供程序,需要在与域模型相同的包中包含一个名为jaxb.properties的文件,并带有以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    演示

    使用这种方法,元素过滤由@XmlPath映射处理,因此运行时部分变得更加简单。请注意,如何仅使用标准的JAXB运行时API

    package forum11586106;
    
    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Countries.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/forum11586106/input.xml");
            Countries countries = (Countries) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(countries, System.out);
        }
    
    }
    

    输入。xml

    <countries>
        <Name language="en">Australia</Name>
        <Name language="se">Australien</Name>
    </countries>
    

    输出

    通过这种方法,language属性包含在输出中:

    <?xml version="1.0" encoding="UTF-8"?>
    <countries>
       <Name language="en">Australia</Name>
    </countries>