Writing Your Own Scanners Warning: this is out of date and needs to be completely rewritten There are two types of scanners, depending on the type of tags that you wish to parse:

- TagScanner - for parsing tags that have no child elements
- CompositeTagScanner - for parsing tags with children

  Your scanner should subclass either of these two classes. You should then register your scanner with the parser with a call like: parser.addScanner(new MyOwnScanner());

  The Anatomy of a Scanner

  The scanner allows you to customize parts of the scanning process. The scanning process is :
  1. Given a tag, match the tag name with a registered scanner
  2. If a match is found (using getId()- which you MUST override), a closer match or special processing can be done by calling the evaluate() method of the scanner. This is optional, subclasses don't have to override the evaluate() method.
  3. If a match was found, call the scan() method. For both TagScanner and CompositeTagScanner, overriding this method is optional, and NOT recommended for standard cases. The default scan() methods will make a call to createTag.
  4. createTag describes the creation of a new tag. This method MUST be overridden in your scanner.

  For your own scanner - simply override :
  1. getID() and have it return an array of strings that will be matched against the tag. For most cases, a single string is enough.
  2. createTag() and have it create your special tag. The data needed for construction of your tag will be within tagData and compositeTagData (mostly within the latter if you are creating a composite tag - a tag with children).

  Note: Tags with children must subclass CompositeTag

  Examples

  1. Simple tag with no children

      public class MySimpleScanner extends TagScanner {
         private static String [] MATCH_ID = {"MYSPECIALTAG"};
         ..
         public String getID() {
             return MATCH_ID;
         }

         protected Tag createTag(TagData tagData, Tag tag, String url) {
            return new MySimpleTag(tagData,..);
         }
      }

      public class MySimpleTag extends Tag {
         public MySimpleTag(TagData,..) {
         }
      }

      2. Composite tag with children

      public class MyCompositeScanner extends CompositeTagScanner {
         private static String [] MATCH_ID = {"MYSPECIALTAG"};
         ..
         public String getID() {
             return MATCH_ID;
         }

         protected Tag createTag(TagData tagData, CompositeTagData compositeTagData) {
            return new MyCompositeTag(tagData,compositeTagData);
         }

      }

      public class MyCompositeTag extends CompositeTag {
         public MyCompositeTag(TagData tagData, CompositeTagData compositeTagData) {
             //..
             // If you wish to collect attributes from the start tag, you could do:
             // String attributeValue = compositeTagData.getStartTag().getAttribute(atributeName);
             //
             // To collect nodes of a particular type,
             // you could do:
             // Node [] myNodes =
             //    compositeTagData.getChildren().searchFor(
             //       SomeTag.class
             //    ).toNodeArray();
         }
      }

      You can customize the composite tag with an array of tag(strings) which indicate when to trigger corrections. You can also specify if you wish to prevent the same tag from appear as its child. Check the javadocs of CompositeTagScanner for more info.

      Last edited on Thursday, January  8, 2004  4:13:18 am.