JAXB 将嵌套元素解组为空

JAXB Unmarshals Nested Element to Null

XML 片段:

<datasource formatted-name="blah" inline="blah">
    <repository-location derived-from="blah" id="blah" path="blah" revision="blah" site="blah"/>
</datasource>

我正在尝试使用嵌套静态 classes 解组一个 class(数据源)下的所有内容。这是我的数据源 class:

@XmlRootElement(name = "datasource")
@XmlAccessorType(XmlAccessType.FIELD)
public class DataSource {

    @XmlAttribute(name = "formatted-name")
    protected String formattedName;
    @XmlAttribute(name = "inline")
    protected String inline;
    @XmlElement(name = "repository-location")
    protected RepositoryLocation repositoryLocation;

    // public getters and setters for fields above

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class RepositoryLocation {

        @XmlAttribute(name = "derived-from")
        protected String derivedFrom;
        @XmlAttribute(name = "id")
        protected String id;
        @XmlAttribute(name = "path")
        protected String path;
        @XmlAttribute(name = "revision")
        protected String revision;
        @XmlAttribute(name = "site")
        protected String site;

        // public getters and setters for fields above
    }
}

解组器:

JAXBContext jaxbContext = JAXBContext.newInstance(DataSource.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(responseXML);
dataSourceResponse = (DataSource) unmarshaller.unmarshal(reader);

我可以成功输出 DataSource 字段 "formattedName" 和 "inline",但 "repositoryLocation" 为空。有人可以帮忙吗?

JAXB 无需 Getters/Setters 即可解组,字段甚至可以是私有的。给定上面的 DataSource class,将一些生成的 toString 方法添加到 DataSourceRepositoryLocation,下面打印出所有属性:

import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import java.io.StringReader;

public class Jaxb {

    public static void main(String[] args) throws JAXBException {
        String xml = "<datasource formatted-name=\"blah\" inline=\"blah\">\n" +
                "    <repository-location derived-from=\"blah\" id=\"blah\"" +
                " path=\"blah\" revision=\"blah\" site=\"blah\"/>\n" +
                "</datasource>";

        JAXBContext context = JAXBContext.newInstance(DataSource.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        DataSource dataSource = (DataSource) unmarshaller.unmarshal(new StringReader(xml));
        System.out.println(dataSource);
    }

    @XmlRootElement(name = "datasource")
    @XmlAccessorType(XmlAccessType.FIELD)
    private class DataSource {

        @XmlAttribute(name = "formatted-name")
        private String formattedName;
        @XmlAttribute(name = "inline")
        private String inline;
        @XmlElement(name = "repository-location")
        private RepositoryLocation repositoryLocation;

        @XmlAccessorType(XmlAccessType.FIELD)
        private class RepositoryLocation {

            @XmlAttribute(name = "derived-from")
            private String derivedFrom;
            @XmlAttribute(name = "id")
            private String id;
            @XmlAttribute(name = "path")
            private String path;
            @XmlAttribute(name = "revision")
            private String revision;
            @XmlAttribute(name = "site")
            private String site;

            @Override
            public String toString() {
                return "RepositoryLocation{" +
                        "derivedFrom='" + derivedFrom + '\'' +
                        ", id='" + id + '\'' +
                        ", path='" + path + '\'' +
                        ", revision='" + revision + '\'' +
                        ", site='" + site + '\'' +
                        '}';
            }
        }

        @Override
        public String toString() {
            return "DataSource{" +
                    "formattedName='" + formattedName + '\'' +
                    ", inline='" + inline + '\'' +
                    ", repositoryLocation=" + repositoryLocation +
                    '}';
        }
    }
}

问题解决了!我注意到我的 java 1.7 库缺少一些 jar。所以我决定继续升级到 1.8。它像魔术一样工作!

也尝试使用 java 1.7 并且它有效并且在 xml.txt 中,xml 被保存

package testSingleJar.specificpackage;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args ) throws Exception
    {
        JAXBContext jaxbContext = JAXBContext.newInstance(DataSource.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        String responseXML =  "";
        //filename is filepath string
        BufferedReader br = new BufferedReader(new FileReader(new File("D:\xml.txt")));
        String line;
        StringBuilder sb = new StringBuilder();

        while((line=br.readLine())!= null){
            sb.append(line.trim());
        }

        responseXML=sb.toString();
        StringReader reader = new StringReader(responseXML);
        DataSource dataSourceResponse = (DataSource) unmarshaller.unmarshal(reader);
        System.out.println(dataSourceResponse.getRepositoryLocation().getDerivedFrom());
    }
}


@XmlRootElement(name = "datasource")
@XmlAccessorType(XmlAccessType.FIELD)
class DataSource {

    @XmlAttribute(name = "formatted-name")
    protected String formattedName;
    @XmlAttribute(name = "inline")
    protected String inline;
    @XmlElement(name = "repository-location")
    protected RepositoryLocation repositoryLocation;

    // public getters and setters for fields above

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class RepositoryLocation {

        @XmlAttribute(name = "derived-from")
        protected String derivedFrom;
        @XmlAttribute(name = "id")
        protected String id;
        @XmlAttribute(name = "path")
        protected String path;
        @XmlAttribute(name = "revision")
        protected String revision;
        @XmlAttribute(name = "site")
        protected String site;
        public String getDerivedFrom() {
            return derivedFrom;
        }
        public void setDerivedFrom(String derivedFrom) {
            this.derivedFrom = derivedFrom;
        }
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getPath() {
            return path;
        }
        public void setPath(String path) {
            this.path = path;
        }
        public String getRevision() {
            return revision;
        }
        public void setRevision(String revision) {
            this.revision = revision;
        }
        public String getSite() {
            return site;
        }
        public void setSite(String site) {
            this.site = site;
        }

    }

    public String getFormattedName() {
        return formattedName;
    }

    public void setFormattedName(String formattedName) {
        this.formattedName = formattedName;
    }

    public String getInline() {
        return inline;
    }

    public void setInline(String inline) {
        this.inline = inline;
    }

    public RepositoryLocation getRepositoryLocation() {
        return repositoryLocation;
    }

    public void setRepositoryLocation(RepositoryLocation repositoryLocation) {
        this.repositoryLocation = repositoryLocation;
    }
}

输出:废话