home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / exml.lha / exml / examples / ebook / ebook_xml_parser.e < prev    next >
Text File  |  1999-04-13  |  6KB  |  297 lines

  1. indexing
  2.     description:"Objects that parse Ebook XML-documents"
  3.     status:        "See notice at end of class."
  4.     author:        "Andreas Leitner"
  5.  
  6. class
  7.     EBOOK_XML_PARSER
  8.  
  9. inherit
  10.     XML_TREE_PARSER
  11.     KL_INPUT_STREAM_ROUTINES
  12.         undefine
  13.             out
  14.         end
  15.     KL_OUTPUT_STREAM_ROUTINES
  16.         rename
  17.             close as close_output,
  18.             is_closed as is_closed_output
  19.         undefine
  20.             out
  21.         end
  22.     EBOOK_GLOBALS
  23.         undefine
  24.             out
  25.         end
  26.  
  27. creation
  28.     make
  29. feature 
  30.     is_valid: BOOLEAN
  31.  
  32. feature
  33.  
  34.     parse_file is
  35.             -- parses a file
  36.             -- also validates it
  37.         local
  38.             in_file: like INPUT_STREAM_TYPE
  39.             buffer: STRING
  40.             ebook_cursor: DS_LINKED_TREE_CURSOR [EBOOK_PAGE]
  41.         do
  42.             in_file := make_file_open_read (ebook_xml_file_name)
  43.  
  44.             check
  45.                 file_open: is_open_read (in_file)
  46.             end
  47.  
  48.             from
  49.             until
  50.                 end_of_input (in_file) or not is_correct
  51.             loop
  52.         
  53.                 buffer := read_string (in_file, 1000)
  54.  
  55.                 if
  56.                     buffer.count > 0
  57.                 then
  58.                     parse_string (buffer)
  59.                 else
  60.                     set_end_of_file    
  61.                 end
  62.  
  63.             end
  64.             close (in_file)
  65.  
  66.             if
  67.                 is_correct
  68.             then
  69.                 post_parse_actions
  70.  
  71.                 validate
  72.  
  73.                 if 
  74.                     is_valid
  75.                 then
  76.                     !! ebook_root.make
  77.                     ebook_root.put_root (Void)
  78.                     ebook_cursor := ebook_root.new_cursor
  79.                     ebook_cursor.to_root
  80.                     generate_ebook_tree (root_element, ebook_cursor)
  81.                 end
  82.  
  83.             end
  84.         end
  85.  
  86. -- Iterating through pages recursively (not needed with Pylon tree)
  87. --
  88.     generate_html_pages is
  89.             -- generates html pages
  90.         require
  91.             is_correct: is_correct
  92.             is_valid: is_valid
  93.         local
  94.             cs: DS_LINKED_TREE_CURSOR [EBOOK_PAGE]
  95.         do
  96.             cs := ebook_root.new_cursor
  97.             cs.to_root
  98.             generate_html_page (cs)
  99.         end
  100.  
  101. feature {NONE}
  102.  
  103.     generate_html_page (cs: DS_LINKED_TREE_CURSOR [EBOOK_PAGE]) is
  104.         require
  105.             cs_not_void: cs /= Void
  106.         local
  107.             file: like OUTPUT_STREAM_TYPE
  108.         do
  109.             from
  110.                 cs.child_start
  111.             until
  112.                 cs.child_off
  113.             loop
  114.                     -- generate this page
  115.                 file := make_file_open_write (cs.child_item.file_name)
  116.                 file.put_string (cs.child_item.html_page)
  117.                 close_output (file)
  118.  
  119.                     -- process recursive pages
  120.                 cs.down
  121.                 generate_html_page (cs)
  122.                 cs.up
  123.  
  124.                 cs.child_forth
  125.             end
  126.  
  127.         end
  128.  
  129. feature {NONE}-- post parsing
  130.  
  131.     post_parse_actions is
  132.         do
  133.             remove_unwanted_children (root_element)
  134.             join_text_nodes (root_element)
  135.         end
  136.  
  137.  
  138.     remove_unwanted_children (node: XML_NODE) is
  139.             -- remove node if:
  140.             -- node is a text block and
  141.             -- parent of node is not a 'text' or 'topic' element
  142.         require
  143.             node_not_void: node /= Void
  144.         local
  145.             text: XML_TEXT
  146.             element: XML_ELEMENT
  147.             cs: DS_BILINKED_LIST_CURSOR [XML_NODE]
  148.         do
  149.             from
  150.                 cs := node.new_cursor
  151.                 cs.start
  152.             until 
  153.                 cs.off
  154.             loop
  155.                 text ?= cs.item
  156.                 if
  157.                     text /= Void and then
  158.                     (not text.parent.name.is_equal ("topic") and
  159.                     not text.parent.name.is_equal ("text"))
  160.                 then    
  161.                     node.remove_at (cs)
  162.                 else
  163.                     remove_unwanted_children (cs.item)
  164.                     cs.forth
  165.                 end
  166.             end        
  167.         end
  168.  
  169.  
  170.     join_text_nodes (node: XML_NODE) is
  171.             -- join all sequences of text nodes
  172.         require
  173.             node_not_void: node /= Void
  174.         local
  175.             element: XML_ELEMENT
  176.             cs: DS_LINKED_LIST_CURSOR [XML_NODE]
  177.         do
  178.             from
  179.                 cs := node.new_cursor
  180.                 cs.start
  181.             until 
  182.                 cs.off
  183.             loop
  184.                 element ?= cs.item
  185.                 if
  186.                     element /= Void
  187.                 then    
  188.                     element.join_text_nodes
  189.                         -- proces recursively
  190.                     join_text_nodes (element)
  191.                 end
  192.                 cs.forth
  193.             end
  194.         end
  195.  
  196. feature {NONE} -- validating
  197.     validate is
  198.             -- needed since the XML-parser is not validating at the moment ):
  199.         require
  200.             is_correct: is_correct
  201.         local
  202.             element: XML_ELEMENT
  203.         do
  204.             is_valid := True
  205.             if
  206.                 not root_element.name.is_equal ("ebook")
  207.             then
  208.                 is_valid := False
  209.             else
  210.                 -- process further pages
  211.             end
  212.         end
  213.  
  214. feature {NONE} -- 
  215.  
  216.     ebook_root: DS_LINKED_TREE [EBOOK_PAGE]
  217.  
  218.     generate_ebook_tree (el: XML_ELEMENT; ebook_cs: DS_LINKED_TREE_CURSOR [EBOOK_PAGE]) is
  219.         require
  220.             is_correct: is_correct
  221.             is_valid: is_valid
  222.             el_not_void: el /= Void
  223.         local
  224.             a_page: EBOOK_PAGE
  225.             a_page_el: XML_ELEMENT
  226.             file_name: STRING
  227.             cs: DS_LINKED_LIST_CURSOR [XML_NODE]
  228.             first_node: BOOLEAN
  229.             current_level: INTEGER
  230.         do
  231.             from
  232.                 cs := el.new_cursor
  233.                 cs.start
  234.                 first_node := True
  235.             until
  236.                 cs.off
  237.             loop
  238.                 a_page_el ?= cs.item
  239.  
  240.                 if
  241.                     a_page_el /= Void and then
  242.                     a_page_el.name.is_equal ("page")
  243.                 then
  244.                         -- generate this page
  245.                     !! a_page.make_from_xml_element (a_page_el, ebook_root)
  246.  
  247.                         -- add page to the tree on the same level
  248.                     if
  249.                         first_node
  250.                     then
  251.                         ebook_root.put_first_child (a_page, ebook_cs)
  252.                         ebook_cs.child_start
  253.                         first_node := False
  254.                             -- add_child automatically goes down one level
  255.  
  256.  
  257.                     else
  258.                         ebook_root.put_right_child (a_page, ebook_cs)
  259.                         ebook_cs.child_forth
  260.                             -- add right stays on the same level
  261.  
  262.                     end
  263.  
  264.                         -- process recursivly (one level deeper - child of current node)
  265.                     current_level := ebook_cs.depth
  266.                     ebook_cs.down
  267.                     generate_ebook_tree (a_page_el, ebook_cs)
  268.                     ebook_cs.up
  269.  
  270.                         -- if we went down a level in the recursion go up again
  271.                     check
  272.                         level_check: current_level = ebook_cs.depth or current_level = ebook_cs.depth - 1
  273.                     end
  274.  
  275.                 end
  276.  
  277.                 cs.forth
  278.             end
  279.         end
  280.  
  281.  
  282.  
  283. end -- class EBOOK_XML_PARSER
  284. --|-------------------------------------------------------------------------
  285. --| eXML, Eiffel XML Parser Toolkit
  286. --| Copyright (C) 1999  Andreas Leitner
  287. --| See the file forum.txt included in this package for licensing info.
  288. --|
  289. --| Comments, Questions, Additions to this library? please contact:
  290. --|
  291. --| Andreas Leitner
  292. --| Arndtgasse 1/3/5
  293. --| 8010 Graz
  294. --| Austria
  295. --| email: andreas.leitner@teleweb.at
  296. --| web: http://exml.dhs.org
  297. --|-------------------------------------------------------------------------