Improve XML parsing to handle attributes as well.
[cfb.git] / prod / net / jaekl / qd / xml / ParseResult.java
index e8210159951327dfbb7646f28c8d05bfe55e7f80..f653b368c81f17f4dee94e8211410e334050f058 100644 (file)
@@ -8,6 +8,7 @@
 
 package net.jaekl.qd.xml;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -67,17 +68,35 @@ public abstract class ParseResult
                }
        }
 
-       public abstract void endContents(String uri, String localName, String qName, String chars, Attributes attr) throws XmlParseException;
+       public abstract void endContents(String uri, String localName, String qName, String chars) throws XmlParseException;
        public abstract void endExternal(String uri, String localName, String qName) throws XmlParseException;
+
+       // Called once for this tag itself
+       public void handleMainAttributes(Attributes attr) throws MissingAttributeException {
+               // Default action is to do nothing.
+               // Override this if you want to process tag attributes.
+       }
+       
+       // Called once for each internally-handled subtag
+       public void handleInternalAttributes(String tagName, Attributes attr) throws MissingAttributeException {
+               // Default action is to do nothing.
+               // Override this if you want to process tag attributes.
+       }
        
        public String getTagName() { return m_tagName; }
-       public boolean haveSeenMyTag() { return m_haveSeenMyTag; }
 
        public void characters(char[] ch, int start, int length) throws XmlParseException
        {
                m_chars.append(ch, start, length);
        }
        
+       // Dump human-readable text describing this tag and its children.
+       // Default implemenation:  print the tag name (only)
+       public void dump(PrintWriter pw, int indent) {
+               String margin = String.format("%"+indent+"s", "");
+               pw.println(margin + getTagName());
+       }
+       
        protected ParseResult[] collectParsedChildren(Class<? extends ParseResult> cls) {
                ArrayList<ParseResult> collection = new ArrayList<ParseResult>();
                Iterator<ParseResult> iter = m_childParsers.iterator();
@@ -94,7 +113,7 @@ public abstract class ParseResult
        }
        
        // returns true if this ParseResult's context has ended with this endElement() call
-       public boolean endElement(String uri, String localName, String qName) throws XmlParseException
+       protected boolean endElement(String uri, String localName, String qName) throws XmlParseException
        {
                assert (null != localName);
                
@@ -122,13 +141,13 @@ public abstract class ParseResult
                }
                
                String chars = m_chars.toString();
-               endContents(uri, localName, qName, chars, info.getAttributes());
+               endContents(uri, localName, qName, chars);
                
                return false;
        }
        
        // returns either itself, or a new ParseResult-derived object, whichever should handle parsing the inside of this element
-       public ParseResult startElement(String uri, String localName, String qName, Attributes attributes) 
+       public ParseResult startElement(String uri, String localName, String qName, Attributes attrs) 
                        throws XmlParseException
        {
                assert (null != localName);
@@ -140,6 +159,7 @@ public abstract class ParseResult
                        
                        if (m_tagName.equals(localName)) {
                                m_haveSeenMyTag = true;
+                               handleMainAttributes(attrs);
                                return this;
                        }
                        else {
@@ -152,7 +172,8 @@ public abstract class ParseResult
                }
 
                if (m_internal.contains(localName)) {
-                       CurrentInfo info = new CurrentInfo(localName, attributes);
+                       handleInternalAttributes(localName, attrs);
+                       CurrentInfo info = new CurrentInfo(localName, attrs);
                        m_current.push(info);
                        return this;
                }
@@ -162,7 +183,7 @@ public abstract class ParseResult
                        try {
                                ParseResult childParser = (ParseResult) parserClass.newInstance();
                                m_childParsers.add(childParser);
-                               return childParser.startElement(uri, localName, qName, attributes);
+                               return childParser.startElement(uri, localName, qName, attrs);
                        }
                        catch (IllegalAccessException iae) {
                                throw new XmlParseException(iae);
@@ -200,5 +221,6 @@ public abstract class ParseResult
                }
                return value;
        }
+
 }