Search code examples
javaapache-commons-digester

Getting a specific value from xml using Digester and XSLT transform to filter out


I am processing an xml file using apache.commons.digester

The xml is, for instance, structured as:

< Files >    
< File Name="ABC.EXE" Version="1.0" Size="3954174" >    
< File Name="XYZ.EXE" Version="2.0" Size="11833856" >    
< File Name="RST.exe" Version="3.0" Size="32768" >    
< Files >

I want to avoid looping through after the Digester parses the xml . Is there any rule I can specify so that I get back only attributes related to file with name="XYZ.EXE'

Update -

Since, I asked this question, I Googled and came upon, http://wiki.apache.org/commons/Digester/FAQ where it says using Digester alone, one cannot access attributes with specific values. One needs to using XSLT transform (org.xml.sax.XMLFilter). I have no idea how to go about that. Still searching for an solution. Any suggestions is welcomed.


Solution

  • Full snippet

    public class Files {
        List<MyFile> list = new ArrayList<MyFile>();
    
        public Files() {
            super();
        }
    
        public boolean addFile(MyFile f) {
            return list.add(f);
        }
    }
    
    public class MyFile {
        public String name;
        public String version;
        public String size;
        public void setName(String name) {
            this.name = name;
        }
        public void setVersion(String version) {
            this.version = version;
        }
        public void setSize(String size) {
            this.size = size;
        }
        @Override
        public String toString() {
            return "MyFile [name=" + name + ", size=" + size + ", version="
                    + version + "]";
        }
    
    }
    
    class ConditionalRule extends ObjectCreateRule {
    
        private boolean conditional = false;
        public ConditionalRule() throws ParserConfigurationException {
            super(MyFile.class);
        }
    
        @Override
        public void begin(String namespaceURI, String name, Attributes attributes)
                throws Exception {
            conditional = "ABC.EXE".equals(attributes.getValue("Name"));
            if(conditional) {
                Files files = (Files) digester.pop();
                MyFile f = new MyFile();
                files.addFile(f);
                digester.push(files);
                digester.push(f);
            }
        }
    
        @Override
        public void end() throws Exception {
            if(conditional) {
                digester.pop();
            }
        }
    
    }
    public class Snippet {
    
        @Test
        public void test() throws Exception {
            Digester d = new Digester();
            d.addObjectCreate("Files", Files.class);
            d.addRule("Files/File", new ConditionalRule());
            d.addSetProperties("Files/File",
                    new String[]{"Name", "Version", "Size"}, new String[]{"name", "version", "size"});
            Object parse = d.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("digest.xml"));
            System.out.println(parse);
        }
    }