XMLC Tutorial: Grouping Document Elements

Contents

  1. Using XMLC for multiple changes
  2. A Sample HTML Page
  3. The Associated Document Object Model (DOM)
  4. Resulting Java Class
  5. Usage from a Manipulation Java Class
  6. Resulting HTML

Using XMLC for multiple changes

This chapter will show how XMLC may be used to make a particular change at several locations throughout a document. There are several ways to do this. We will demonstrate two of them: changing all tags of a particular type, and changing all tags with a common name attribute value.

A Sample HTML Page

The following sample HTML contains several <h2> tags, and several tags with a <name> attribute.


<HTML>
<HEAD>
    <TITLE>Hello, World</TITLE>
</HEAD>

<BODY BGCOLOR=#FFFFFF TEXT="#000000">

<H1>Hello, World</H1>

<H2>A subheader</H2>

We want to <FONT COLOR='00FF00' NAME='highlight'>highlight</FONT> part of
this sentence. 

<H2>Another subheader</H2>

In this sentence, we display the colors <FONT COLOR='FF0000'>red</FONT>,
<FONT COLOR='00FF00'>green</FONT> and <FONT COLOR='0000FF'>blue</FONT>. 

<P>
The previous sentence <FONT COLOR='00FF00' NAME='highlight'>did not use
color to highlight text</FONT>!

</BODY>
</HTML>

The Associated Document Object Model (DOM)

XMLC generates the following Document Object Model (DOM) for the above HTML.


DOM hierarchy:
    HTMLDocument:null DocumentType
        HTMLHtmlElement: HTML
            HTMLHeadElement: HEAD
                HTMLTitleElement: TITLE
                    Text: Hello, World
            HTMLBodyElement: BODY: bgcolor='#FFFFFF' text='#000000'
                HTMLHeadingElement: H1
                    Text: Hello, World
                HTMLHeadingElement: H2
                    Text: A subheader
                Text: We want to 
                HTMLFontElement: FONT: color='00FF00' name='highlight'
                    Text: highlight
                Text:  part of this sentence. 
                HTMLHeadingElement: H2
                    Text: Another subheader
                Text: In this sentence, we display the colors 
                HTMLFontElement: FONT: color='FF0000'
                    Text: red
                Text: , 
                HTMLFontElement: FONT: color='00FF00'
                    Text: green
                Text:  and 
                HTMLFontElement: FONT: color='0000FF'
                    Text: blue
                Text: . 
                HTMLParagraphElement: P
                    Text: The previous sentence 
                    HTMLFontElement: FONT: color='00FF00' name='highlight'
                        Text: did not use color to highlight text
                    Text: !

Resulting Java Class

XMLC generates the following Java class for the above HTML. Unlike the <id> attribute, XMLC does not special Java code for the <name>. However, we can use methods defined in W3C's Document Object Model API.


/*
 ************************************
 * XMLC GENERATED CODE, DO NOT EDIT *
 ************************************
 */
import org.w3c.dom.*;
import org.enhydra.xml.xmlc.XMLCUtil;
import org.enhydra.xml.xmlc.XMLCError;
import org.enhydra.xml.xmlc.dom.XMLCDomFactory;

public class demo_grouping extends org.enhydra.xml.xmlc.html.HTMLObjectImpl {
    /**
     * Field that is used to identify this as an XMLC
     * generated class.  Contains an reference to the
     * class object.
     */
    public static final Class XMLC_GENERATED_CLASS = demo_grouping.class;

    /**
     * Field containing CLASSPATH relative name of the source file
     * that this class was generated from.
     */
    public static final String XMLC_SOURCE_FILE = "nulldemo_grouping.html";

    /**
     * Element name constant for highlight
     */
    public static final String NAME_highlight = "highlight";
    /**
     * Create document as a DOM and initialize accessor method fields.
     */
    public void buildDocument() {
        XMLCDomFactory domFactory = org.enhydra.xml.xmlc.dom.XMLCDomFactoryCache.getFactory("org.enhydra.xml.xmlc.dom.DefaultHTMLDomFactory");
        Document document = domFactory.createDocument(null, null);
        setDocument(document);

        domFactory.setErrorChecking(document, false);

        Node $node0, $node1, $node2, $node3, $node4;
        Element $elem0, $elem1, $elem2, $elem3;
        Attr $attr0, $attr1, $attr2, $attr3;

        $elem0 = document.getDocumentElement();
        $elem1 = document.createElement("HEAD");;
        $elem0.appendChild($elem1);
        
        $elem2 = document.createElement("TITLE");;
        $elem1.appendChild($elem2);
        
        $node3 = document.createTextNode("Hello, World");;
        $elem2.appendChild($node3);
        
        $elem1 = document.createElement("BODY");;
        $elem0.appendChild($elem1);
        
        $attr1 = document.createAttribute("bgcolor");
        $elem1.setAttributeNode($attr1);
        
        $node2 = document.createTextNode("#FFFFFF");;
        $attr1.appendChild($node2);
        
        $attr1 = document.createAttribute("text");
        $elem1.setAttributeNode($attr1);
        
        $node2 = document.createTextNode("#000000");;
        $attr1.appendChild($node2);
        
        $elem2 = document.createElement("H1");;
        $elem1.appendChild($elem2);
        
        $node3 = document.createTextNode("Hello, World");;
        $elem2.appendChild($node3);
        
        $elem2 = document.createElement("H2");;
        $elem1.appendChild($elem2);
        
        $node3 = document.createTextNode("A subheader");;
        $elem2.appendChild($node3);
        
        $node2 = document.createTextNode("We want to ");;
        $elem1.appendChild($node2);
        
        $elem2 = document.createElement("FONT");;
        $elem1.appendChild($elem2);
        
        $attr2 = document.createAttribute("color");
        $elem2.setAttributeNode($attr2);
        
        $node3 = document.createTextNode("00FF00");;
        $attr2.appendChild($node3);
        
        $attr2 = document.createAttribute("name");
        $elem2.setAttributeNode($attr2);
        
        $node3 = document.createTextNode("highlight");;
        $attr2.appendChild($node3);
        
        $node3 = document.createTextNode("highlight");;
        $elem2.appendChild($node3);
        
        $node2 = document.createTextNode(" part of this sentence. ");;
        $elem1.appendChild($node2);
        
        $elem2 = document.createElement("H2");;
        $elem1.appendChild($elem2);
        
        $node3 = document.createTextNode("Another subheader");;
        $elem2.appendChild($node3);
        
        $node2 = document.createTextNode("In this sentence, we display the colors ");;
        $elem1.appendChild($node2);
        
        $elem2 = document.createElement("FONT");;
        $elem1.appendChild($elem2);
        
        $attr2 = document.createAttribute("color");
        $elem2.setAttributeNode($attr2);
        
        $node3 = document.createTextNode("FF0000");;
        $attr2.appendChild($node3);
        
        $node3 = document.createTextNode("red");;
        $elem2.appendChild($node3);
        
        $node2 = document.createTextNode(", ");;
        $elem1.appendChild($node2);
        
        $elem2 = document.createElement("FONT");;
        $elem1.appendChild($elem2);
        
        $attr2 = document.createAttribute("color");
        $elem2.setAttributeNode($attr2);
        
        $node3 = document.createTextNode("00FF00");;
        $attr2.appendChild($node3);
        
        $node3 = document.createTextNode("green");;
        $elem2.appendChild($node3);
        
        $node2 = document.createTextNode(" and ");;
        $elem1.appendChild($node2);
        
        $elem2 = document.createElement("FONT");;
        $elem1.appendChild($elem2);
        
        $attr2 = document.createAttribute("color");
        $elem2.setAttributeNode($attr2);
        
        $node3 = document.createTextNode("0000FF");;
        $attr2.appendChild($node3);
        
        $node3 = document.createTextNode("blue");;
        $elem2.appendChild($node3);
        
        $node2 = document.createTextNode(". ");;
        $elem1.appendChild($node2);
        
        $elem2 = document.createElement("P");;
        $elem1.appendChild($elem2);
        
        $node3 = document.createTextNode("The previous sentence ");;
        $elem2.appendChild($node3);
        
        $elem3 = document.createElement("FONT");;
        $elem2.appendChild($elem3);
        
        $attr3 = document.createAttribute("color");
        $elem3.setAttributeNode($attr3);
        
        $node4 = document.createTextNode("00FF00");;
        $attr3.appendChild($node4);
        
        $attr3 = document.createAttribute("name");
        $elem3.setAttributeNode($attr3);
        
        $node4 = document.createTextNode("highlight");;
        $attr3.appendChild($node4);
        
        $node4 = document.createTextNode("did not use color to highlight text");;
        $elem3.appendChild($node4);
        
        $node3 = document.createTextNode("!");;
        $elem2.appendChild($node3);
        

        domFactory.setErrorChecking(document, true);

    }

    /**
     * Recursize function to do set access method fields from the DOM.
     * Missing ids have fields set to null.
     */
    protected void syncWithDocument(Node node) {
        if (node instanceof Element) {
            String id = ((Element)node).getAttribute("id");
            if (id.length() == 0) {
            }
        }
    }

    /**
     * Default constructor.
     */
    public demo_grouping() {
        buildDocument();
    }

    /**
     * Constructor with optional building of the DOM. 
     *
     * @param buildDOM If false, the DOM will not be built until
     * buildDocument() is called by the derived class.  If true, 
     * the DOM is built immediatly.
     */
    public demo_grouping(boolean buildDOM) {
        if (buildDOM) {
            buildDocument();
        }
    }

    /**
     * Copy constructor.
     * @param src The document to clone.
     */
    public demo_grouping(demo_grouping src) {
        setDocument((Document)src.getDocument().cloneNode(true));
        syncAccessMethods();
    }

    /**
      * Clone the document.
      * @param deep Must be true, only deep clone is supported.
      */
    public Node cloneNode(boolean deep) {
        cloneDeepCheck(deep);
        return new demo_grouping(this);
    }

}

Usage from a Manipulation Java Class


import org.w3c.dom.*;
import org.w3c.dom.html.*;

public class demo_grouping_creator {

    private static void centerSubheaders( NodeList nodeList ){

        int length = nodeList.getLength(); 
        int i ; 

        for( i=0 ; i<length ; i++ ){ 
            HTMLElement element = (HTMLElement) nodeList.item( i ); 
            element.setAttribute( "ALIGN", "CENTER" ); 
        }

    }

    private static void alterHighlighting( NodeList nodeList ){

        int length = nodeList.getLength(); 
        int i ; 

        for( i=0 ; i<length ; i++ ){ 
            HTMLElement element = (HTMLElement) nodeList.item( i ); 
            element.removeAttribute( "COLOR" ); 
            element.setAttribute( "SIZE", "+2" ); 
        }

    }
   
    public static void main (String[] args) {
    
        // Create an instance of the HTML page object.
        demo_grouping grouping = new demo_grouping();
    
        // Get a list of all H2 elements
        NodeList subheaderElements = grouping.getElementsByTagName( "H2" ); 
    
        // Add an 'ALIGN=CENTER' attribute to these elements
        centerSubheaders( subheaderElements ); 
    
        // Get a list of all nodes with name 'highlight'
        NodeList highlightElements = grouping.getElementsByName( "highlight" ); 
    
        // In these elements, replace the COLOR attribute with a FONT attribute
        alterHighlighting( highlightElements ); 
    
        // Print out the results.
        System.out.print( grouping.toDocument() );
    
    }

}

In the above Java, the highlighted code shows how to extract a NodeList of DOM elements. The first highlighted code shows how to find all tags of a given type, in this case the <h2> tag. The second highlighted section shows how to extract all tags with a given value for the <name> attribute, in this case <name="highlight">.

The two methods centerSubheaders() and alterHighlighting() show how to scan a NodeList, processing each element in turn, and how to manipulate the attributes of a given element.

It is possible to do much more sophisticated processing of the DOM, but that goes beyond the scope of this document. We suggest you peruse the Java DOM API javadoc.

Resulting HTML

Here is the HTML page created by the above example:


<HTML>
<HEAD><TITLE>Hello, World</TITLE></HEAD>
<BODY bgcolor='#FFFFFF' text='#000000'>
<H1>Hello, World</H1>
<H2 align='CENTER'>A subheader</H2>
We want to 
<FONT color='00FF00' name='highlight' size='+2'>highlight</FONT> 
part of this sentence. 
<H2 align='CENTER'>Another subheader</H2>
In this sentence, we display the colors <FONT color='FF0000'>red</FONT> , 
<FONT color='00FF00'>green</FONT> and <FONT color='0000FF'>blue</FONT> . 
<P>
The previous sentence <FONT color='00FF00' name='highlight' size='+2'>
did not use color to highlight text </FONT> !
</BODY>
</HTML>

Once again, the whitespace in the above example HTML is added by hand. XMLC removes as much whitespace as possible.