Filtering XML Documents

The previous example displayed the entire document, but as we saw in the previous chapter, you can be more selective than that through a process called filtering. When you filter a document, you extract only those elements you're interested in.

Here's a new example named ch12_04.java. In this case, I'll let the user specify what document to search and what element name to search for. This will display all <ITEM> elements in ch12_01.xml:

 %java ch12_04 ch12_01.xml ITEM 

This program is not difficult to write, now that we've written the indenting parser example. Note, however, that we have to handle not just the specific element that the user is searching for, but also the element's children that are contained inside the element. I'll adapt the ch12_03.java application to create ch12_04.java; all we'll have to control is when we display elements and when we do not. If the current element matches the element the user is searching for, I'll set a Boolean variable named printFlag to true :

 public void startElement(String uri, String localName, String qualifiedName, graphics/ccc.gif Attributes attributes)      {  if(qualifiedName.equals(searchFor)){   printFlag=true;   }  .     .     . } 

Now I can check whether printFlag is true and, if so, add the current element and its attributes to the display strings:

 public void startElement(String uri, String localName, String qualifiedName, graphics/ccc.gif Attributes attributes)      {         if(qualifiedName.equals(searchFor)){             printFlag=true;         }  if (printFlag){   displayStrings[numberDisplayLines] = indent;   indent += "    ";   displayStrings[numberDisplayLines] += '<';   displayStrings[numberDisplayLines] += qualifiedName;   if (attributes != null) {   int numberAttributes = attributes.getLength();   for (int loopIndex = 0; loopIndex < numberAttributes; loopIndex++) {   displayStrings[numberDisplayLines] += ' ';   displayStrings[numberDisplayLines] += attributes.getLocalName( graphics/ccc.gif loopIndex);   displayStrings[numberDisplayLines] += "=\"";   displayStrings[numberDisplayLines] += attributes.getValue(loopIndex);   displayStrings[numberDisplayLines] += '"';   }   }   displayStrings[numberDisplayLines] += '>';   numberDisplayLines++;   }   }  

And I can do the same in other callback methods that add text to the displayStrings array, such as the character callback:

 public void characters(char characters[], int start, int length) {  if(printFlag){   String characterData = (new String(characters, start, length)).trim();   if(characterData.indexOf("\n") < 0 && characterData.length() > 0) {   displayStrings[numberDisplayLines] = indent;   displayStrings[numberDisplayLines] += characterData;   numberDisplayLines++;   }   }  } 

Note that we don't want to set printFlag to false until after the element that the user is searching for ends, at which point we've displayed the whole element and all its children. When the element ends, I set printFlag to false this way:

 public void endElement(String uri, String localName, String qualifiedName)  {     if(printFlag){         indent = indent.substring(0, indent.length() - 4);         displayStrings[numberDisplayLines] = indent;         displayStrings[numberDisplayLines] += "</";         displayStrings[numberDisplayLines] += qualifiedName;         displayStrings[numberDisplayLines] += '>';         numberDisplayLines++;     }  if(qualifiedName.equals(searchFor)){   printFlag=false;   }  } 

That's all it takes. I'll filter ch12_01.xml for <ITEM> elements like this:

 %java ch12_04 ch12_01.xml ITEM   MORE 

You can see the results in Figure 12-2, where I'm filtering ch12_01.xml to find all <ITEM> elements.

Figure 12-2. Filtering an XML document using a SAX parser.

graphics/12fig02.gif

Here's the complete code:

Listing ch12_04.java
 import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.*; import java.io.*; public class ch12_04 extends DefaultHandler {     static String displayStrings[] = new String[1000];     static int numberDisplayLines = 0;     static String indent = "";     static boolean printFlag;     static String searchFor;     public void displayDocument(String uri)     {         DefaultHandler handler = this;         SAXParserFactory factory = SAXParserFactory.newInstance();         try {             SAXParser saxParser = factory.newSAXParser();             saxParser.parse(new File(uri), handler);         } catch (Throwable t) {}     }     public void processingInstruction(String target, String data)     {         if(printFlag){             displayStrings[numberDisplayLines] = indent;             displayStrings[numberDisplayLines] += "<?";             displayStrings[numberDisplayLines] += target;             if (data != null && data.length() > 0) {                 displayStrings[numberDisplayLines] += ' ';                 displayStrings[numberDisplayLines] += data;             }             displayStrings[numberDisplayLines] += "?>";             numberDisplayLines++;         }     }     public void startDocument()     {         if(printFlag){             displayStrings[numberDisplayLines] = indent;             displayStrings[numberDisplayLines] += "<?xml version=\"1.0\" encoding=\""+                 "UTF-8" + "\"?>";             numberDisplayLines++;         }     }     public void startElement(String uri, String localName, String qualifiedName, graphics/ccc.gif Attributes attributes)     {         if(qualifiedName.equals(searchFor)){             printFlag=true;         }         if (printFlag){             displayStrings[numberDisplayLines] = indent;             indent += "    ";             displayStrings[numberDisplayLines] += '<';             displayStrings[numberDisplayLines] += qualifiedName;             if (attributes != null) {                 int numberAttributes = attributes.getLength();                 for (int loopIndex = 0; loopIndex < numberAttributes; loopIndex++) {                     displayStrings[numberDisplayLines] += ' ';                     displayStrings[numberDisplayLines] += attributes.getLocalName( graphics/ccc.gif loopIndex);                     displayStrings[numberDisplayLines] += "=\"";                     displayStrings[numberDisplayLines] += attributes.getValue(loopIndex);                     displayStrings[numberDisplayLines] += '"';                 }             }             displayStrings[numberDisplayLines] += '>';             numberDisplayLines++;         }     }     public void characters(char characters[], int start, int length) {         if(printFlag){             String characterData = (new String(characters, start, length)).trim();             if(characterData.indexOf("\n") < 0 && characterData.length() > 0) {                 displayStrings[numberDisplayLines] = indent;                 displayStrings[numberDisplayLines] += characterData;                 numberDisplayLines++;             }         }     }     public void ignorableWhitespace(char characters[], int start, int length)     {         if(printFlag){             //characters(ch, start, length);         }     }     public void endElement(String uri, String localName, String qualifiedName)     {         if(printFlag){             indent = indent.substring(0, indent.length() - 4);             displayStrings[numberDisplayLines] = indent;             displayStrings[numberDisplayLines] += "</";             displayStrings[numberDisplayLines] += qualifiedName;             displayStrings[numberDisplayLines] += '>';             numberDisplayLines++;         }         if(qualifiedName.equals(searchFor)){             printFlag=false;         }     }     public void warning(SAXParseException exception)     {         System.err.println("WARNING! " +             exception.getMessage());     }     public void error(SAXParseException exception)     {         System.err.println("ERROR! " +             exception.getMessage());     }     public void fatalError(SAXParseException exception)     {         System.err.println("FATAL ERROR! " +             exception.getMessage());     }     public static void main(String args[])     {         ch12_04 obj = new ch12_04();         searchFor = args[1];         obj.displayDocument(args[0]);         for(int index = 0; index < numberDisplayLines; index++){             System.out.println(displayStrings[index]);         }     } } 

The examples we've created so far have all created text-based output using the System.out.println method. As noted in the previous chapter, however, few browsers these days work that way. In the next section, I'll take a look at creating a windowed browser.



Real World XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 440
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net