【问题标题】:JAXB Unmarshals Nested Element to NullJAXB 将嵌套元素解组为 Null
【发布时间】:2017-02-08 08:42:21
【问题描述】:

XML sn-p:

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

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

@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”为空。有人可以帮忙吗?

【问题讨论】:

  • 它应该可以工作。你有 repositoryLocation 的 getter/setter 吗?
  • 是的,我有。
  • 你如何解组?请添加代码。

标签: java xml jaxb unmarshalling


【解决方案1】:

JAXB 能够在没有 Getter/Setter 的情况下解组,并且字段甚至可以是私有的。鉴于上面的DataSource 类,将一些生成的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 +
                    '}';
        }
    }
}

【讨论】:

  • 这是我得到的:DataSource{formattedName='Individual BI Mart (copy)', inline='true', version='9.2', xmlBase='null', xmlnsUser='null' , repositoryLocation=null}
  • 这种方式可行,但需要在内部类名定义中添加静态。谢谢!
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    也尝试过使用 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;
        }
    }
    

    输出:废话

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多