home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / exml.lha / exml / main / xml_parser_abs.e < prev    next >
Text File  |  1999-04-13  |  8KB  |  268 lines

  1. indexing
  2.     description: "Class for parsing XML documents"
  3.     status: "See notice at end of class."
  4.     author: "Andreas Leitner"
  5.  
  6. deferred class
  7.     XML_PARSER_ABS
  8. inherit
  9.     EXPAT_ERROR_CODES
  10.     EXPAT_EXTERNALS
  11.         rename
  12.             get_base as get_base_expat,
  13.             set_base as set_base_expat
  14.         end
  15.     EXML_EXTERNALS
  16.  
  17. feature {NONE}  -- Initialisation
  18.     make is
  19.         do
  20.             item := parser_create (default_pointer)
  21.  
  22.             exml_register_start_end_tag_hook (item)
  23.             exml_register_content_hook (item)
  24.             exml_register_processing_instruction_hook (item)
  25.         --    exml_register_default_hook (item)
  26.                 -- registering the default hook, prevents the parser
  27.                 -- from expanding internal  entity-references
  28.             exml_register_unparsed_entity_declaration_hook (item)
  29.             exml_register_notation_declaration_hook (item)
  30.             exml_register_external_entity_reference_hook (item)
  31.             exml_register_unkown_encoding (item)
  32.  
  33.             set_eiffel_object_as_user_data
  34.         end
  35.  
  36.  
  37. feature {ANY} -- operations
  38.  
  39.     parse_string (data: STRING) is
  40.             -- Parse 'data'.
  41.             -- Note: You can call parse_string multiple times
  42.             -- and give the parse the document in parts only.
  43.             -- You have to call 'set_end_of_file' after the
  44.             -- last call to 'parse_string' in every case.
  45.         require
  46.             data_not_void: data /= Void
  47.         do
  48.             if
  49.                 parse_string_imp (data) = 0
  50.                     -- function call with side effect !!!!
  51.             then
  52.                 last_error := get_error_code (item)    
  53.             end
  54.         end
  55.  
  56.     set_end_of_file is
  57.             -- Call this routine to
  58.             -- tell the parser that the document has been
  59.             -- completly parsed and no input is comming anymore.
  60.         local
  61.             int_result: INTEGER
  62.             a: ANY
  63.             s: STRING
  64.         do
  65.             int_result := parse (item, default_pointer, 0, 1)
  66.  
  67.             if
  68.                 int_result = 0
  69.             then
  70.                 last_error := get_error_code (item)    
  71.             end
  72.         end
  73.  
  74. feature -- Access
  75.     last_error: INTEGER
  76.             -- see XML_PARSER_ERROR_CODES
  77.  
  78.     is_correct: BOOLEAN is
  79.             -- returns False if an error was detected
  80.             -- by the parser
  81.         do
  82.             Result := last_error = Xml_error_none
  83.         ensure
  84.             error_flag_set: (Result = True) implies (last_error = Xml_error_none)
  85.             error_flag_set2: (Result = False) implies (last_error /= Xml_error_none)
  86.         end
  87.  
  88.  
  89.     last_error_description: STRING is deferred end
  90.             -- gives a text that explain 'last_error'
  91.  
  92.     last_error_extended_description: STRING is
  93.             -- extended description of 'last_error'
  94.         do
  95.             !! Result.make (0)
  96.             Result.append (last_error_description)
  97.             Result.append ("(")
  98.             Result.append (last_error.out)
  99.             Result.append (") at ln: ")
  100.             Result.append (last_line_number.out)
  101.             Result.append (", cl: ")
  102.             Result.append (last_column_number.out)
  103.         end
  104.  
  105.     last_line_number: INTEGER is deferred end
  106.             -- current line number (works in callback too)
  107.     last_column_number: INTEGER is deferred end
  108.             -- current column number (works in callback too)
  109.     last_byte_index: INTEGER is deferred end
  110.             -- current byte index (works in callback too)
  111.  
  112.     set_base (a_base: STRING) is deferred end
  113.             -- sets the base to be used for resolving URIs in system identifiers
  114.             -- in declarations. 
  115.     get_base: STRING is deferred end
  116.             -- returns the base
  117.  
  118. feature {NONE} -- Redefinable Callbacks
  119.     on_start_tag (start_tag: XML_START_TAG) is
  120.             -- called whenever the parser findes a start element
  121.         require
  122.             start_tag_not_void: start_tag /= Void
  123.         do
  124.         end
  125.  
  126.     on_content (content: XML_CONTENT) is
  127.             -- called whenever the parser findes character data
  128.         require
  129.             content_not_void: content /= Void
  130.         do
  131.         end
  132.  
  133.     on_end_tag (end_tag: XML_END_TAG) is
  134.             -- called whenever the parser findes an end element
  135.         require
  136.             end_tag_not_void: end_tag /= Void
  137.         do
  138.         end
  139.     on_default (data: CHARACTER_ARRAY) is
  140.         -- this feature is called for any character in the XML
  141.         -- document for which there is no applicable handler
  142.     
  143.         require
  144.             data_not_void: data /= Void
  145.         do
  146.         end
  147.  
  148. feature {NONE} -- Implementation
  149.  
  150.     pass_to_default_handler is
  151.             -- can be called within a start, end, processing instruction,
  152.             -- and content handler to pass the current markup to the default handler
  153.             -- TODO: work out dbc to ensure it is called only from the
  154.             -- good features!
  155.         do
  156.             pass_to_defaul_handler (item)
  157.         end
  158.     
  159. feature {NONE} -- (low level) frozen callbacks (called from eXML clib)
  160.  
  161.     frozen on_start_tag_procedure (tag_name_ptr, attribute_specifications_ptr: POINTER) is
  162.         require
  163.             tag_name_ptr_not_void: tag_name_ptr /= Void
  164.             attribute_specifications_ptr_not_void: attribute_specifications_ptr /= Void
  165.         local
  166.             start_tag: XML_START_TAG
  167.         do
  168.             !! start_tag.make_from_c (tag_name_ptr, attribute_specifications_ptr)
  169.             on_start_tag (start_tag)
  170.         end
  171.  
  172.     frozen on_end_tag_procedure (tag_name_ptr: POINTER) is
  173.         local
  174.             end_tag: XML_END_TAG
  175.         do
  176.             !! end_tag.make_from_c (tag_name_ptr)
  177.             on_end_tag (end_tag)
  178.         end
  179.  
  180.     frozen on_content_procedure (content_ptr: POINTER; len: INTEGER) is
  181.         local
  182.             content: XML_CONTENT
  183.         do
  184.             !! content.make_from_c (content_ptr, len)
  185.             on_content (content)
  186.         end
  187.  
  188.     frozen on_processing_instruction_procedure (target, data: POINTER) is
  189.         do
  190.             print ("found processing_instruction (HELP!!!)%N")
  191.                 -- TODO: Don't really know yet. If you know please let me know too (:
  192.         end
  193.  
  194.     frozen on_default_procedure_address (data_ptr: POINTER; len: INTEGER) is
  195.         local
  196.             data: CHARACTER_ARRAY
  197.         do
  198.             !! data.make_from_c (data_ptr, len)
  199.             on_default (data)
  200.         end
  201.  
  202.     frozen on_unparsed_entity_declaration_procedure (enitity_name, base, system_id, public_id, notation_name: POINTER) is
  203.         do
  204.             print ("found unparsed_entity_declaration (HELP!!!)%N")
  205.                 -- TODO: Don't really know yet. If you know please let me know too (:
  206.     
  207.         end
  208.     frozen on_notation_declaration_procedure (notation_name, base, system_id, public_id: POINTER) is
  209.         do
  210.             print ("found notation_declaration (HELP!!!)%N")
  211.                 -- TODO: Don't really know yet. If you know please let me know too (:
  212.         end
  213.  
  214.     frozen on_external_entity_reference_procedure (open_entity_name, base, system_id, public_id: POINTER): INTEGER is
  215.             -- return zero if parsing of external entity was not successfull
  216.             -- 'base' is a char* pointing to data previously set with 'set_base'
  217.         do
  218.             print ("found external_entity_reference (HELP!!!)%N")
  219.             Result := 1
  220.                 -- TODO: Well,, I guess I need to start another parser here - always?
  221.                 -- maybe this should be configurable
  222.                 -- anyway there needs to be some expat stuff encapsulated first (XML_ExternalEntityParserCreate)
  223.                 -- this function is used to create a parse, that parses those external references.
  224.                 -- I assume this will be a heir from XML_PARSER.
  225.         end
  226.  
  227.     frozen on_unkown_encoding_procedure (name, info: POINTER): INTEGER is
  228.         do
  229.             print ("found unkown_encoding (HELP!!!)%N")
  230.                 -- TODO: Don't really know yet. If you know please let me know too (:
  231.         end
  232.  
  233. feature {NONE}
  234.  
  235.     parse_string_imp  (data: STRING): INTEGER is
  236.             -- function has side effect !!!
  237.         require
  238.             data_not_void: data /= Void
  239.         deferred 
  240.         end
  241.  
  242.     set_eiffel_object_as_user_data is deferred end
  243.             -- expat hooks receive a user defineble integer as
  244.             -- additional parameter. we set this to the Eiffel
  245.             -- parser object.
  246.  
  247.     item: POINTER
  248.         -- the expat parser handle
  249.  
  250.     
  251.  
  252. invariant
  253.     item_not_void: item /= Void
  254. end    -- XML_PARSER_ABS
  255. --|-------------------------------------------------------------------------
  256. --| eXML, Eiffel XML Parser Toolkit
  257. --| Copyright (C) 1999  Andreas Leitner
  258. --| See the file forum.txt included in this package for licensing info.
  259. --|
  260. --| Comments, Questions, Additions to this library? please contact:
  261. --|
  262. --| Andreas Leitner
  263. --| Arndtgasse 1/3/5
  264. --| 8010 Graz
  265. --| Austria
  266. --| email: andreas.leitner@teleweb.at
  267. --| web: http://exml.dhs.org
  268. --|-------------------------------------------------------------------------