We have a large set of configuration documents of the style
...more content
You could do something like the following with JAXB (JSR-222) and StAX (JSR-173):
Demo
A StAX XMLStreamReader
can be used to parse the XML document. You can use it to advance to a bar
element, then you can read the class
attribute and load the appropriate Java class from a ClassLoader
. Then you can leverage one of the unmarshal
methods that takes a class parameter.
package forum12402215;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
ClassLoader classLoader = Bork.class.getClassLoader();
JAXBContext jc = JAXBContext.newInstance(Bork.class, Gnarf.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource source = new StreamSource("src/forum12402215/input.xml");
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(source);
xsr.nextTag(); // Advance to "foo" element
xsr.nextTag(); // Advance to "bar" element
while(xsr.getLocalName().equals("bar")) {
String className = xsr.getAttributeValue("", "class");
Class<?> clazz = classLoader.loadClass(className);
Object object = unmarshaller.unmarshal(xsr, clazz).getValue();
System.out.println(object);
xsr.nextTag();
}
}
}
Bork
Below is a sample Bork
class.
package forum12402215;
public class Bork {
private String b;
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
@Override
public String toString() {
return "Bork(b=" + b + ")";
}
}
Gnarf
Below is a sample Gnarf
class:
package forum12402215;
public class Gnarf {
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
@Override
public String toString() {
return "Gnarf(a=" + a + ")";
}
}
input.xml
Below is he sample document I used used for this example based on the one from your question. I changed the package names.
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar class="forum12402215.Gnarf">
<a>123</a>
</bar>
<bar class="forum12402215.Bork">
<b>Hello World</b>
</bar>
</foo>
Output
Below is the output from running the demo code.
Gnarf(a=123)
Bork(b=Hello World)
If the structure really is that simple I'd be tempted to parse the top two levels (foo and the class attribute of bar) myself using an XMLStreamReader
, then hand the reader off to the JAXB unmarshaller to parse each bar, assembling the results into a list. I wouldn't bother trying to parse the outer envelope layers using JAXB directly.