【问题标题】:Can we create a java object from an xml without knowing what object it is belong to我们可以在不知道它属于哪个对象的情况下从 xml 创建一个 java 对象吗
【发布时间】:2013-03-27 02:26:53
【问题描述】:

我有一个 xml 内容,我不知道它属于哪个类。我需要使用 XML 中可用的信息创建一个动态 java 对象。有可能这样做吗?它可能是简单的 java 对象,然后我们可以使用 java 反射从该对象中获取值。例如,

<Employee>
  <name>Jack</name>
  <designation>Manager</designation>
  <department>Finance</department>
</Employee>

所以,我需要从这个 xml 转换为 Employee 对象。但是,我的类路径中没有 Employee 类。是否可以使用提供的 XML 创建对象?

【问题讨论】:

  • 这是在运行时? XML 可以是任何格式还是特定格式?
  • 是的,它在运行时,XMl 可以是任何格式....
  • 你可以用足够通用的东西来表示 XML 对象,比如HashMap&lt;String, Object&gt;。如果你想使用特定的类,你必须限制可能性。
  • 可以在byte[]load it 中构建class file,但这并不容易;您是否有充分的理由需要将 XML 加载到动态创建的类型中?
  • 如果 XML 可以是任何格式,你怎么知道你想访问什么?反射数据检索背后的逻辑是什么?我之所以问,是因为我认为这是 XPath 的经典候选者,但我不完全确定您的用例。

标签: java xml-serialization


【解决方案1】:
File fXmlFile = new File("Employee.xml");
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(fXmlFile);

    //optional, but recommended
    //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
    doc.getDocumentElement().normalize();

    System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

    NodeList nList = doc.getElementsByTagName("Employee");

    System.out.println("----------------------------");

    for (int temp = 0; temp < nList.getLength(); temp++) {

        Node nNode = nList.item(temp);

        System.out.println("\nCurrent Element :" + nNode.getNodeName());

        if (nNode.getNodeType() == Node.ELEMENT_NODE) {

            Element eElement = (Element) nNode;

            System.out.println("Name        :- " + eElement.getElementsByTagName("name").item(0).getTextContent());
            System.out.println("Designation :-" + eElement.getElementsByTagName("designation").item(0).getTextContent());
            System.out.println("Department  :- " + eElement.getElementsByTagName("department").item(0).getTextContent());


        }
    }

【讨论】:

  • 这看起来很有用,我们可以解析内部节点吗?例如,如果我有 XML 作为 JackManagerFinance1员工>。我可以动态迭代并打印值以及节点名称吗?
【解决方案2】:

您可以使用 JCodemodel 动态生成 java 类。 JCodeModel 在 1.6 + jdk 中随 JAX-B 一起提供,并且还分拆为托管在 http://codemodel.java.net/ 的单独项目。

对于代码生成,您需要查找需要使用解析 API 的 DOM/SAX/Stax API 的 XML 节点类型。但是,如果只有 XML 可用,就不可能管理每个 Java 属性的数据类型。如果您可以只使用 String 属性,那么探索这条路径就可以了。

【讨论】:

    【解决方案3】:

    您可以解析 XML 并生成对象的源代码。

    使用您的示例,生成的类将是:

    public class Employee {
    
        private String name;
        private String designation;
        private String department;
    
        public Employee(String name, String designation, String department) {
            this.name = name;
            this.designation = designation;
            this.department = department;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDesignation() {
            return designation;
        }
    
        public void setDesignation(String designation) {
            this.designation = designation;
        }
    
        public String getDepartment() {
            return department;
        }
    
        public void setDepartment(String department) {
            this.department = department;
        }
    
    }
    

    您使用大量 StringBuilder 方法生成这样的代码。这是我的 Java 项目中的一种方法。此方法为针对数据库执行 SQL 的类生成执行选择尝试块。

    protected static final String DELIM_LINE = System
            .getProperty("line.separator");
    
    
    protected StringBuilder generateExecuteSelectTryBlock(String ps,
            StringBuilder variables) {
        StringBuilder sb = new StringBuilder();
        sb.append("\t\ttry {");
        sb.append(DELIM_LINE);
        sb.append("\t\t\tprepare");
        sb.append(ps);
        sb.append("Select(");
        if (variables != null) {
            sb.append(variables);
        }
        sb.append(");");
        sb.append(DELIM_LINE);
        sb.append("\t\t\tResultSet rs = ps");
        sb.append(ps);
        sb.append(".executeQuery();");
        sb.append(DELIM_LINE);
        sb.append("\t\t\treturn rs;");
        sb.append(DELIM_LINE);
        sb.append("\t\t} catch (SQLException e) {");
        sb.append(DELIM_LINE);
        sb.append("\t\t\tif (e.getErrorCode() == +100) return null;");
        sb.append(DELIM_LINE);
        sb.append("\t\t\tDB2Connection.sqlException(e);");
        sb.append(DELIM_LINE);
        sb.append("\t\t}");
        sb.append(DELIM_LINE);
        sb.append("\t\treturn null;");
        sb.append(DELIM_LINE);
        return sb;
    }
    

    【讨论】:

    • 我认为这个问题更多的是关于如何源将被生成而不是源本身。
    • 是的,这就是我想要的,我该如何解析 XML 并生成源代码。任何代码示例都会有所帮助..
    • 此代码无需质疑。他需要实例化类 Object 依赖于 XML。
    • @bmorris591: output.write(" public class Employee {");冲洗并重复。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多