Java XML – JDOM2 – Filters

JDOM2 has three methods that accepts Filters while obtaining data. The three methods are

  • &ltE extends Content&gt List&ltE&gt getContent(Filter&ltE&gt filter);
  • &ltE extends Content&gt List&ltE&gt removeContent(Filter&ltE&gt filter);
  • &ltE extends Content&gt IteratorIterable&ltE&gt getDescendants(Filter&ltE&gt filter);

Filters are also extensively used in the JDOM2 XPath API, especially to ‘coerce the xpath result data in to the generic-typed results’. See
this
tutorial on xpath to understand how Filters are used in the JDOM2 XPath API.

The main classes are :

  1. org.jdom2.filter.AbstractFilter – Contains partial implementation of org.jdom2.filter.Filter
  2. org.jdom2.filter.ContentFilter – Filters various JDOM2 objects such as ELEMENT, CDATA, TEXT, COMMENT, PI, ENTITYREF, DOCUMENT and DOCTYPE. It can also filter a group of Objects such as both ELEMENT and COMMENT.
  3. org.jdom2.filter.ElementFilter – Allows org.jdom2.Element
  4. org.jdom2.filter.AttributeFilter – Allows org.jdom2.Attribute
  5. org.jdom2.filter.Filters – Factory class to create other filters. Most users will use this class to create filters. The most important methods of this class are :
    • public static final Filter&ltAttribute&gt attribute() – matches Attribute
    • public static final Filter&ltAttribute&gt attribute(String name) – matches Attribute with a specific name.
    • public static final Filter&ltAttribute&gt attribute(String name, Namespace ns) – matches Attribute with a specific name in a specific namespace.
    • public static final Filter&ltAttribute&gt attribute(Namespace ns) – matches Attribute within a specified namespace.
    • public static final Filter&ltComment&gt comment() – matches Comment.
    • public static final Filter&ltCDATA&gt cdata() – matches CDATA.
    • public static final Filter&ltDocType&gt doctype() – matches DocType.
    • public static final Filter&ltEntityRef&gt entityref() – matches EntityRef.
    • public static final Filter&ltElement&gt element() – matches Element.
    • public static final Filter&ltDocument&gt document() – matches Document.
    • public static final Filter&ltElement&gt element(String name) – matches Element with a specified name.
    • public static final Filter&ltElement&gt element(String name, Namespace ns) – matches Element with a specified name and namespace.
    • public static final Filter&ltElement&gt element(Namespace ns) – .matches all Elements within a specified namespace
    • public static final Filter&ltProcessingInstruction&gt processinginstruction() – matches Processing Instruction.
    • public static final Filter&ltText&gt text() – matches Text (including CDATA).
    • public static final Filter&ltText&gt textOnly() – matches Text (exclusing CDATA).
    • public static final Filter&ltBoolean&gt fboolean() – matches Boolean data.
    • public static final Filter&ltString&gt fstring() – matches String data.
    • public static final Filter&ltDouble&gt fdouble() – matches Double data.
    • public static final &ltF&gt Filter&ltF&gt fclass(Class&ltF&gt clazz) – matches a specified class.
    • public static final Filter&ltObject&gt fpassthrough() – matches everything, does not filterFd.

The following operations can be performed on a filter

  • public Filter&lt? extends Object&gt negate() – returns Objects NOT matched by the filter.
  • public Filter&lt? extends Object&gt or(Filter&lt?&gt filter) – returns Objects that are passed by any one of the filters
  • public Filter&ltT&gt and(Filter&lt?&gt filter) – returns objects matched by both the filters.
  • public &ltR&gt Filter&ltR&gt refine(Filter&ltR&gt filter) – Similar to the ‘and’ filter but the generic type of the result is taken from the generic type of the input

The class diagram
Class Diagram

Lets look at an example

package com.studytrails.xml.jdom;
 
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.Text;
import org.jdom2.filter.ContentFilter;
import org.jdom2.filter.Filter;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.util.IteratorIterable;
 
public class FilterJdom2 {
    private static String xmlSource = "http://feeds.bbci.co.uk/news/technology/rss.xml?edition=int";
 
    public static void main(String[] args) throws JDOMException, IOException {
        SAXBuilder jdomBuilder = new SAXBuilder();
        Document jdomDocument = jdomBuilder.build(xmlSource);
 
        Element rss = jdomDocument.getRootElement();
        Element channel = rss.getChild("channel");
 
        Element title = channel.getChild("title");
 
        // Content Filter
        ContentFilter filter = new ContentFilter(ContentFilter.PI);
        List cDataContents = jdomDocument.getContent(filter);
        Iterator cDataIterator = cDataContents.iterator();
        while (cDataIterator.hasNext()) {
            Content cdata = cDataIterator.next();
            // System.out.println(cdata.getCType());
            // System.out.println(cdata.getValue());
        }
 
        // Text Filter
        Filter textFilter = Filters.text();
        IteratorIterable channelTextList = channel.getDescendants(textFilter);
        while (channelTextList.hasNext()) {
            Text channelText = channelTextList.next();
            // System.out.println(channelText.getValue());
        }
 
        // or filter
        Filter filters = (Filter) Filters.element("thumbnail", rss.getNamespace("media")).or(Filters.element("link"));
        IteratorIterable thumbnailsAndLinks = channel.getDescendants(filters);
        while (thumbnailsAndLinks.hasNext()) {
            Element thumbnailorLink = thumbnailsAndLinks.next();
            // System.out.println(thumbnailorLink.getName());
        }
 
        // negate filter
        Filter negateFilter = (Filter) Filters.element("link").negate().and(Filters.text().negate());
        IteratorIterable nonLinkElements = channel.getDescendants(negateFilter);
        while (nonLinkElements.hasNext()) {
            Element nonLinkElement = nonLinkElements.next();
            System.out.println(nonLinkElement.getName());
        }
 
    }
}


Leave a Comment