1

I have an xml content, for which i don't know to what class it is belongs to. I need to create a dynamic java object with the info available from the XML. Is it possible to do so ?. It may be the simple java object, then we can use java reflection to get the values from that object. For example,

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

So, from this xml, i need to convert to Employee object. But, i didn't have Employee class in my classpath. Is that possible to create an object with the XML provided ?

sonicwave
  • 5,952
  • 2
  • 33
  • 49
speruri
  • 73
  • 2
  • 10
  • This is at runtime? Can the XML be of any format or is it a specific format? – Boris the Spider Mar 26 '13 at 17:59
  • Yes, it is in Runtime, XMl can be in any format.... – speruri Mar 26 '13 at 18:02
  • 2
    You could represent the XML object with something general enough, like `HashMap`. If you want to use specific classes, you'll have to limit the possibilities. – Vincent van der Weele Mar 26 '13 at 18:02
  • It's possible to build a [class file](http://docs.oracle.com/javase/specs/jvms/se5.0/html/ClassFile.doc.html) in a `byte[]` and [load it](http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#defineClass), but it's not easy to do; is there a good reason you need your XML to load into dynamically created types? – Russell Zahniser Mar 26 '13 at 18:06
  • If the XML can be in any format how do you know what you want to access? What would be the logic behind the reflective data retrieval? I'm asking because I think this is a classic candidate for XPath but I'm not entirely sure of your use case. – Boris the Spider Mar 26 '13 at 18:10
  • Just curious on XML parsing, if we know how to parse an XML, then why can't we create an dynamic Object based on the structure of XML, for example depending on the tags of XML. Is that possible depending on the structure of XML ? – speruri Mar 26 '13 at 18:11
  • As @RussellZahniser says this is possible - you can even write a class as a `String` then call the compiler. It just seems pointless if you have to reflect on it anyway... – Boris the Spider Mar 26 '13 at 18:14
  • @speruri Do you really need to use Java? This is so much easier in some other programming languages... – Vincent van der Weele Mar 26 '13 at 18:32

3 Answers3

0
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());


        }
    }
Akshay Joy
  • 1,765
  • 1
  • 14
  • 23
  • This seems useful and can we parse the internal Nodes. For example, if i have XML as Jack Manager Finance1 . Can i iterate dynamically and print the values along with the node name ? – speruri Mar 26 '13 at 18:38
0

You can use JCodemodel to generate java classes on the fly. JCodeModel comes with JAX-B in 1.6 + jdk and has also spun off as separate project hosted at http://codemodel.java.net/.

For code generation, you will need to look up the XML node types for which you will need to use DOM/SAX/Stax APIs which are parsing API. However, with only XML available it will be impossible to manage the data type of each Java attribute. If you are ok with having only String attributes, then its fine to explore this path.

Akhilesh Singh
  • 2,548
  • 1
  • 13
  • 10
-1

You could parse the XML and generate the source code for an object.

Using your example, the generated class would be:

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;
    }

}

You generate code like this with lots of StringBuilder methods. Here's one method from a Java project of mine. This method generates an execute select try block for a class that performs SQL against a database.

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;
}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111