CSCI 5733.1
XML Application Development
Fall 2002
Final Examination

Name:  _________________________________

Time allowed: one hour and 20 minutes.  Total score: 100%.

Open: text book, lecture notes, every file I wrote and posted in my Web page and your project assignments.  No other materials are allowed.

Answer all questions.  Turn in both question and answer sheets (with the question sheets on top).  Plan your time well.

Academic honesty policy will be followed strictly.  Cheating will result in a failing grade of D or below and a permanent academic record. 

(1) Write a simple XSLT program, keepx.xsl, to accept an XML document, remove all attributes except those with values of "x" and output the resulting XML document.

For example, if the input XML document is:

<?xml version="1.0" ?>
<root a="1" b="x" c="3">
   <p d="x"><q /></p>
   <r c="1" />
   Hello
   <s e="x">
   Bye
   </s>
</root>

The output XML should be (with the possible exception of whitespaces)

<?xml version="1.0" encoding="UTF-8"?>
<root b="x">
   <p d="x">
<q/>
</p>
   <r/>
   Hello
   <s e="x">
   Bye
   </s>
</root>

The skeleton of the XSL program is:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" />

<!-- Your XSL code here -->

</xsl:stylesheet>

You only need to write your XSLT templates.

(2) Consider the following XML file, which is used in the classroom:

<?xml version="1.0"?>
<!-- head comments -->
<familytree>
    <!-- second level comments -->
   <meta>Becker</meta>
    <person ssn="s123456789" gender="M" luckynumber="7">
       <!-- third level comments -->
        <first>Boris</first>
        <last>Becker</last>  
        <email>boris@becker.com</email>
        <email>boris@hotmail.com</email>
        <link spouse="s111222333" children="s123123123 s222333444" father="s555987323" mother="s887667545" />
    </person>
   <?br ?>
   <?nl ?>
    <person ssn="s111222333" gender="F" luckynumber="6">   
        <first>Valerie: <![CDATA[<valerie@cl.uh.edu> & CS student
      </first>
        <last>Becker</last>
        <email>valerie@hotmail.com</email>
        <link spouse="s123456789" children="s123123123 s222333444"></link>  
    </person>
    <person ssn="s123123123" gender="M" luckynumber="4">
        <first>Chris</first>
        <last>Becker</last>
        <email>chris@becker.com</email>
        <link father="s123456789" mother="s111222333" luckynumber="10" />
    </person>
    <person ssn="s222333444" gender="F">   
        <first>Julie</first>
        <last>Becker</last>
        <email>julie@hotmail.com</email>
        <link father="s123456789" mother="s111222333" />
    </person>
    <person ssn="s555987323" gender="M">
        <first>John</first>
        <last>Becker</last>
        <email>john@becker.com</email>
        <link spouse="s887667545" children="s123456789"/>
    </person>
    <person ssn="s887667545" gender="F">   
   <first>Mary</first><last>Becker</last> 
   <email>mary@hotmail.com</email>
    <link spouse="s555987323" children="s123456789"  />
    </person>
</familytree>

Give the XPath expressions to select the followings.

(a) Every person element with more than one email addresses.
(b) The first name element of the spouse of "Boris Becker".
(c) The number of females.
(d) Every element that has no attribute.
(e) The person element immediately after the person with ssn "s111222333".

(3) Write a Java program, NumDescendant.java, to use JDOM (DOM or SAX will not be accepted), to output the same input XML file, except that a new attribute "numDescendants" is added to every element. The value of the new attribute is the number of descendant elements of the current element.

For example, if the input file NumDescendants1.xml is:

<?xml version="1.0" encoding="UTF-8"?>
<a x="1">
   <b y="2" z="3" />
   <c />
   <d w="4">
      <e>
         <f />
      </e>
   </d>
</a>

Running the program:

java NumDescendant NumDescendants1.xml

should print the following to the standard output:

<?xml version="1.0" encoding="UTF-8"?>
<a x="1" numDescendants="5">
   <b y="2" z="3" numDescendants="0" />
   <c numDescendants="0" />
   <d w="4" numDescendants="2">
      <e numDescendants="1">
         <f numDescendants="0" />
      </e>
   </d>
</a>

As an example, note that numDescendants for <a> is 5 as <a> has <b>, <c>, <d>, <e> and <f> as descendant.

The following skeleton is provided for you, so it is only necessary for you to provide the code for the method addDescendantCount (and possibly other helping methods).

import java.io.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import java.util.*;

public class NumDescendant {

   public static void main(String argv[]) {
      if(argv.length == 1) {
         Document document = readDocument(argv[0]);
         if (document != null) {
            int rootDescendantCount = addDescendantCount(document.getRootElement());
            outputDocument(document);
         }
      }
   }

   private static Document readDocument(String filename) {
        try {
            SAXBuilder builder = new SAXBuilder();
            Document result = builder.build(new File(filename));
            return result;
        } catch(JDOMException e) {
            e.printStackTrace();
        } catch(NullPointerException e) {
            e.printStackTrace();
        }
        return null;
    }
   /*
   The body of the following method should be developed:

   private static int addDescendantCount(Element element)

   The method add the numDescendants attributes to element
   and its descendant and return the number of descendants
   of element.
   */

    private static void outputDocument(Document document) {
        try {
         //  indent three spaces and apply newlines.
            XMLOutputter outputter = new XMLOutputter("   ", true);
            outputter.output(document, System.out);
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
    }
}   //   NumDescendant