JAXB unmarshalling of “generic” real world documents

后端 未结 2 1249
死守一世寂寞
死守一世寂寞 2021-01-23 06:37

We have a large set of configuration documents of the style


  
    ...more content
  
  

        
2条回答
  •  粉色の甜心
    2021-01-23 07:23

    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.

    
    
        
            123
        
        
            Hello World
        
    
    

    Output

    Below is the output from running the demo code.

    Gnarf(a=123)
    Bork(b=Hello World)
    

提交回复
热议问题