Srikanth Technologies

Displaying XML with JSF DataTable

In this blog, let us see how to display data that is in XML document as HTML table using dataTable UI component of JSF.

Take the following steps to read data from XML document - books.xml, load it into an ArrayList as object of Book class using managed bean - Books and then the data from a property of managed bean is displayed using dataTable of JSF.

Creating XML Document

The following is XML document - book.xml, which is placed in root directory of the web application.
<?xml version="1.0" encoding="windows-1252"?>
<books>
   <book>
       <title>JSF In Action </title>
       <author>Kito D. Mann </author>
       <price>550</price>
   </book>
   <book>
       <title>Struts 2 In Action </title>
       <author>Brown, David , Stanlink</author>
       <price>500</price>
   </book>
   <book>
       <title>Beginning Hibernate (From Novice to Professional) </title>
       <author>Dave Minter and Jeff Linwood</author>
       <price>299</price>
   </book>
   <book>
       <title>Oracle Database 11g  SQL</title>
       <author>Jason Price</author>
       <price>499</price>
   </book>
   
   <book>
       <title>Java Complete Reference</title>
       <author>Herbert Schildt</author>
       <price>499</price>
   </book>
</books>

Creating required classes

Place classes Book and Books in /WEB-INF/classes folder. Book class represents a single book. Books class provides getBooks() method that is used from JSF dataTable component. It returns an object of ArrayList that contains Book objects.
// Book.java
public class Book {
      private String title, author;
      private int price;
      public Book() {}
      public Book(String title, String author, int price) {
          this.title= title;
          this.author = author;
          this.price = price;
      }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
}
//Books.java
import java.io.File;
import java.util.ArrayList;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Books {
    public ArrayList getBooks() {
        ArrayList al = new ArrayList();
        Book b;
        
        // read data from XML file
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        Document  document;
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            // get physical path for BOOKS.XML. First get access to ServletContext using FacesContext
            ServletContext context = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
            
            String filepath = context.getRealPath("/books.xml");  // get physical path for /books.xml
            document = builder.parse( new File(filepath));
            Element root = document.getDocumentElement();
            NodeList books  =  root.getChildNodes();
            for (int i = 0 ; i < books.getLength(); i ++)
            {
                // skip the rest if node is not an elemtn
	            if ( books.item(i).getNodeType() != Node.ELEMENT_NODE)
	               continue;
	               
                NodeList bookdetails = books.item(i).getChildNodes();
                
                // create a book with the data from book element in XML document
                b = new Book( bookdetails.item(1).getTextContent(),
                                   bookdetails.item(3).getTextContent(),
                                   Integer.parseInt(bookdetails.item(5).getTextContent())) ;
                al.add(b);  // add book to ArrayList
            }
            return al;
        } 
        catch (Exception e) {
           System.out.println("\n** Parsing error" + ", line " + e.getMessage());
           return null;
        }
    }
}

Register ManagedBean in faces-config.xml

Add <managed-bean> element in faces-config.xml as follows to register Books as managed bean.
  <managed-bean>
        <managed-bean-name>Books</managed-bean-name>
        <managed-bean-class>Books</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>
  

Creating JSP to display data that is taken from Managed bean.

Create listbooks.jsp, which uses dataTable element of JSF to read data from books property of Books managed bean and displays it.

JSP uses internal stylesheet with style header to display header of dataTable with red background and white foreground. It uses styles row1 for odd rows and row2 for even rows.
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>List Of Books</title>
        <style>
        .header {background-color:red;color:white;font:700 12pt arial}            
        .row1 {}
        .row2 { background-color:#dddddd}
        </style>
            
    </head>
    <body>
        <h1>List Of Books</h1>
        <f:view>
            <h:form>
                <h:dataTable value="#{Books.books}" var="book"  border="1" 
                headerClass="header"   rowClasses="row1,row2">
                    <h:column>
                        <f:facet name="header"> <f:verbatim>Title</f:verbatim> </f:facet>
                        <h:outputText value="#{book.title}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header"> <f:verbatim>Author</f:verbatim> </f:facet>
                        <h:outputText value="#{book.author}"/>
                    </h:column>
                    
                    <h:column>
                        <f:facet name="header"> <f:verbatim>Price</f:verbatim> </f:facet>
                        <h:outputText  value="#{book.price}"/>
                    </h:column>
                </h:dataTable>
            </h:form>
            
        </f:view>
    </body>
</html>
That's all you have to do to load data from XML document into a managed bean. Once data is loaded into managed bean then it can be accessed from dataTable element of JSF using its value attribute as shown in the above JSP.