CSCI 5931A.1
XML Application Development
Spring 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) Consider the following DTD, ft.dtd:

<!ENTITY uhcl "University of Houston-Clear Lake">
<!ELEMENT familytree (person)+>
<!ELEMENT person (first, last, email*, link?)>
<!ATTLIST person ssn ID #REQUIRED>
<!ATTLIST person gender (M|F) #IMPLIED
             lucknumber (NMTOKEN) #IMPLIED>
<!ELEMENT first (#PCDATA)>
<!ELEMENT last (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT link EMPTY>
<!ATTLIST link
   spouse IDREF #IMPLIED
   children IDREFS #IMPLIED>
<!ATTLIST link
   father IDREF #IMPLIED
   mother IDREF #IMPLIED
   siblings IDREFS #IMPLIED >

A conforming xml (ft.xml):

<?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>       

(a) Give the XPath expression to select the following.

  1. All attribute nodes.
  2. All person element nodes of persons who have a husband
  3. All luckynumber attribute notes with values > 4.
  4. All attribute nodes except the 'father' attribute nodes.
  5. The first name of the person with a ssn of 's111222333'.

(b) What is the result of the XPath expression: "/./././*".

(2) Write a simple XSLT program to accept an XML document and output another XML document with the same XML tree structure, but with all attributes and text removed. An attribute numAttribute, with value equals to the original number of attributes of the element, is then added to every element.

For example, if the input XML document is:

<?xml version="1.0"?>
<root a="1" b="2" c="3">
  <p a="1">hello</p>
  <q a="1" b="2" c="3" d="4">
     <r />
  </q>
  <p a="1" />
</root>

The output XML should be:

<?xml version="1.0" encoding="UTF-8"?>
<root numAttributes="3">
  <p numAttributes="1"/>
  <q numAttributes="4">
    <r numAttributes="0"/>
  </q>
  <p numAttributes="1"/>
</root>

For example, the value of numAttributes for q is 4 since the element q has four attributes (a, b, c and d) in the input XML document. Note that indentation has been added to the output for clarify and it is not necessary to handle output indentation in your program.

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.

(3) Write a Java program, ElementWithComment.java, to use DOM (not JDOM) to count the number of elements with embedded comments in an XML file. An element should be counted if there is a comment embedded inside the element subtree.

For the input file ElementWithComment.xml:

<?xml version="1.0"?>
<!--  top level comment -->
<root>
   <a>
      <b>123      <!-- Some comments  -->
      </b>
      <c>456<d>789</d></c>
      <e>         <!-- Another comment  -->
         <f/>
         <g><h>   <!-- Yet another comment -->
         </h></g>
      </e>
   </a>
</root>

the answer should be 6 since there are six elements with embedded comments: <root>, <a>, <b>, <e>, <g> and <h>.

Therefore, running:

java ElementWithComment ElementWithComment.xml

gives the following output:

For the XML file ElementWithComment.xml,
number of elements with comments: 6.

You don't to write the entire program, the following skeleton has been written for you:

Skeleton of ElementWithComment.java:

import javax.xml.parsers.*;

import org.xml.sax.SAXException; 
import org.xml.sax.SAXParseException; 

import java.io.*;
Import org.w3c.dom.*;

public class ElementWithComment {
    static Document document;

   //   main body
    public static void main(String argv[])
    {
        if (argv.length != 1) {
            System.err.println("Usage: Java ElementWithComment xmlfilename");
            System.exit(1);
        }

        DocumentBuilderFactory factory =
            DocumentBuilderFactory.newInstance();
        try {
         //  Parse input XML file.
         DocumentBuilder builder = factory.newDocumentBuilder();
           document = builder.parse(new File(argv[0]));

         //   Get and print element counts.
         System.out.println("For the XML file " + argv[0] + ",");
         System.out.println("number of elements with comments: "
          + etElementWithCommentCount(document.getDocumentElement())
          + ".");
        } catch (Throwable e) {
           //   Print error messages.
        System.err.println("Sorry, cannot parse the input XML file "
                        + argv[0] + ".");
        }
    } // main

   //  You should give the definition of the method
   //  getElementWithCommentCount here.
   //  ...
 
}

As you can see, the method getElementWithCommentCount returns the required result and you only need to give its definition in your answer.