[Gd-chatter] r10778 - trunk/libraries/xml-parser

turbo24prg at gwydiondylan.org turbo24prg at gwydiondylan.org
Sun Jun 4 20:03:42 CEST 2006


Author: turbo24prg
Date: Sun Jun  4 20:03:40 2006
New Revision: 10778

Modified:
   trunk/libraries/xml-parser/library.dylan
   trunk/libraries/xml-parser/stream-parser.dylan
Log:
Bug: 7306
* simple sax-like parser working now
  but still incomplete


Modified: trunk/libraries/xml-parser/library.dylan
==============================================================================
--- trunk/libraries/xml-parser/library.dylan	(original)
+++ trunk/libraries/xml-parser/library.dylan	Sun Jun  4 20:03:40 2006
@@ -150,6 +150,7 @@
   use %productions;
 
   export <xml-stream-parser>,
-    stream, stream-setter, parse;
+    stream, stream-setter,
+    parse, monitor;
     
 end module xml-stream-parser;

Modified: trunk/libraries/xml-parser/stream-parser.dylan
==============================================================================
--- trunk/libraries/xml-parser/stream-parser.dylan	(original)
+++ trunk/libraries/xml-parser/stream-parser.dylan	Sun Jun  4 20:03:40 2006
@@ -3,9 +3,15 @@
 author: 
 copyright:
 
+/*
+** - monitor
+** - parse -> dispatch -> handle
+*/
+
 define class <xml-stream-parser> (<object>)
   slot stream :: <stream>,
     required-init-keyword: stream:;
+  slot handlers :: <table> = make(<table>);
   slot opened-elements :: <deque> = make(<deque>);
   slot text-buffer :: <string> = "";
   slot tag-buffer :: <string> = "";
@@ -13,10 +19,13 @@
   slot parsing-root? :: <boolean> = #f;
 end class <xml-stream-parser>;
 
+define method monitor (parser :: <xml-stream-parser>, event :: one-of(#"start-element", #"end-element", #"characters"), handler :: <function>)
+  parser.handlers[event] := handler;
+end method monitor;
+  
 define method parse (parser :: <xml-stream-parser>)
   while (~ stream-at-end?(parser.stream))
     let received = read-element(parser.stream);
-
     dispatch(parser, received, parser.parsing-tag?, parser.parsing-root?);
   end while;
 end method parse;
@@ -29,10 +38,10 @@
 end method;
 
 define method dispatch (parser :: <xml-stream-parser>, char == '<', in-tag? == #f, in-root? == #t) => ();
-///!!! signal (text)
-///??? even if only whitespaces?
+  handle-characters(parser, parser.text-buffer);
   parser.text-buffer := "";
-  next-method();
+  parser.parsing-tag? := #t;
+  parser.tag-buffer := add!(parser.tag-buffer, char);
 end method;
 
 define method dispatch (parser :: <xml-stream-parser>, char :: <character>, in-tag? == #f, in-root? == #f) => ();
@@ -57,18 +66,27 @@
   block (skip-next)
     let (index, start-tag, attributes, opened-element?) = scan-start-tag(parser.tag-buffer);
     if (start-tag)
-      if (opened-element?) push-last(parser.opened-elements, start-tag) end if;
-//!!! call handle-start-tag (start-tag, attributes, opened-element?)
+      start-tag := as(<string>, start-tag);
+      handle-start-element(parser, start-tag, attributes);
+      if (opened-element?) 
+        push-last(parser.opened-elements, start-tag) 
+      else
+        handle-end-element(parser, start-tag);
+      end if;
+      parser.parsing-root? := #t;
       skip-next();
     end if;
     
     let (index, end-tag) = scan-end-tag(parser.tag-buffer);
     if (end-tag)
-      if (as(<symbol>, end-tag) ~= last(parser.opened-elements))
+      if (end-tag ~= last(parser.opened-elements))
 //!!! error (tag mismatch)
       else
         pop-last(parser.opened-elements);
-//!!! call handle-end-tag (end-tag)
+        handle-end-element(parser, end-tag);
+      end if;
+      if (size(parser.opened-elements) = 0)
+        in-root? := #f;
       end if;
       skip-next();
     end if;
@@ -88,6 +106,14 @@
   instance?(char, one-of('\n', '\t', '\r'))
 end method whitespace?;
 
-define method handle-tag-start (parser :: <xml-stream-parser>, name :: <symbol>, attributes :: <sequence>)
-  
-end method handle-tag-start;
+define method handle-start-element (parser :: <xml-stream-parser>, name, attributes :: <sequence>)
+  parser.handlers[#"start-element"](name, attributes);
+end method handle-start-element;
+
+define method handle-end-element (parser :: <xml-stream-parser>, name)
+  parser.handlers[#"end-element"](name);
+end method handle-end-element;
+
+define method handle-characters (parser :: <xml-stream-parser>, text :: <string>)
+  parser.handlers[#"characters"](text);
+end method handle-characters;



More information about the chatter mailing list