Search code examples
javaxmljaxbmarshallingunmarshalling

Storing elements inside a custom array ( Casting help)


I parse my XML(root tag -- "Registry") and store in a object of type Registry. Eg: XML

<?xml version="1.0"?>
<Registry>
    <Schools>
        <School loc= "XXX">
            <Student name = "XXX"/>
            <Student name = "XX1"/>
            <Student name = "XX2"/>
        </School>
        
        <School loc= "YYY">
            <Student name = "XXX"/>
            <Student name = "XY1"/>
            <Student name = "XY2"/>
        </School>
        
        <School loc= "ZZZ">
            <Student name = "YXX"/>
            <Student name = "YX1"/>
            <Student name = "YX2"/>
        </School>
        
        <School loc= "AAA">
            <Student name = "ZXX"/>
            <Student name = "ZX1"/>
            <Student name = "ZX2"/>
        </School>
        
    </Schools>
</Registry>

The XML is unmarshalled as below and stored in the object of root tag type.

File xmlFile = new File("studteachobjmodel.xml");
JAXBContext jaxbContext;
jaxbContext = JAXBContext.newInstance(Registry .class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Registry xmlentries = (Registry) jaxbUnmarshaller.unmarshal(xmlFile);

Now if i have a series of such XML files, I declare an array object of type Registry[] xmlentries I want to store the XML entries in the array of the Registry Type. I have done the following, but it shows an error

    Registry[]xmlentries = null;
    JAXBContext jaxbContext;
    File dir = new File("XMLFiles");
    if (dir.exists() && dir.isDirectory()) {
        FileFilter filter = new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return file.isFile() && file.getName().endsWith(".xml");
                }
            };
        File [] files = dir.listFiles(filter);
        if (files != null) {                    
                for (int i =0;i <files.length;i++) {    
                    jaxbContext = JAXBContext.newInstance(Registry.class);
                    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
                    xmlentries[i] = (Registry) jaxbUnmarshaller.unmarshal(files[i]); //ERROR
                    
                }
            }
        
        }

The error:

Exception in thread "main" java.lang.NullPointerException: Cannot store to object array because "xmlentries" is null
    at code.GenerateXML.main(GenerateXML.java:31)


Any hint to overcome this please. TIA


Solution

  • You never initialize your array xmlentries.

    Registry[] xmlentries = null;
    

    So when you try to assign an object to it here

    xmlentries[i] = (Registry) jaxbUnmarshaller.unmarshal(files[i]);
    

    it will throw a NullPointerException.

    You should either use a List, a Set or intialize your array if you absolutely want an array

    Registry[] xmlentries = new Registry[10]; (for an array of 10 elements for instance).

    or if you want an array of the size of your number of files

        [...]
        File [] files = dir.listFiles(filter);
        if (files != null) {  
                xmlentries = new Registry[files.length]; <-- intialization of your array here                  
                for (int i = 0;i < files.length;i++) {    
        [...]
    

    However, I would suggest you to use a Set (if you want unique entries) or a List (if you want order), it's easier to manipulate than an array.

    Set<Registry> entries = new Hashet<>();
    List<Registry> entries = new ArrayList<>();