Search code examples
javaxmlxml-parsingdom4j

Accessing subElements in dom4j


Below is the XML which I am using.

<xxx>
  <yyy>
    <zzz>
        <tag name="name1">
            <innerEle attr = "qaqq">
        </tag>
        <tag name="name2">
            <innerEle attr = "qaqq">
        </tag>
    <zzz>
  <yyy>
</xxx>

For the above xml I have a root element

Now If I want to access "innerEle" element I can either use Xpath or by Iteration .

Is there any other way to access this element as Iteration might take more time

Please provide suggestions to access it without Xpath or by Iteration

Currently I am using dom4j.jar[version 2.1.1].


Solution

  • You could create a custom DocumentFactory that creates some sort of index on those elements that you are interested in, and access them through that index. Details would be quite specific to the use case.

    public static void main(String[] args) throws Exception {
        SelectiveIndexedDocumentFactory factory = new SelectiveIndexedDocumentFactory(QName.get("innerEle"));
        SAXReader reader = new SAXReader();
        reader.setDocumentFactory(factory);
        Document doc = reader.read(...);
    
        factory.getElements(QName.get("innerEle")).stream()
            .forEach(e -> System.out.println(e.getName()));
    
    }
    
    
    static class SelectiveIndexedDocumentFactory extends DocumentFactory {
        private Set<QName> indexedElements = new HashSet<>();
    
        private Map<QName, List<Element>> index = new HashMap<>();
    
        public SelectiveIndexedDocumentFactory(QName...indexedElements) {
            this.indexedElements.addAll(Arrays.asList(indexedElements));
        }
    
        public List<Element> getElements(QName qn) {
            return index.containsKey(qn) ? index.get(qn) : Collections.emptyList();
        }
    
    
        @Override
        public Element createElement(QName qname) {
            Element e = super.createElement(qname);
            if (indexedElements.contains(qname)) {
                List<Element> l = index.get(qname);
                if (l == null) {
                    l = new ArrayList<>();
                    index.put(qname, l);
                }
                l.add(e);
            }
            return e;
        }
    
    }