indexing description: "The document builder implements the gobo XM_CALLBACKS interface and when it% % is being used by a gobo parser, it will build the DOM tree of the parsed% % document" author: "Lukas Angerer" date: "$Date$" revision: "$Revision$" class DOCUMENT_BUILDER inherit XM_CALLBACKS_NULL redefine on_start, on_start_tag, on_start_tag_finish, on_end_tag, on_content, on_attribute, on_xml_declaration, on_processing_instruction end create make_doc feature -- Creation make_doc (doc: XML_DOCUMENT) is -- creates a new document builder for the given document do document := doc create elements.make -- put the document (root of the DOM tree) on top of the element stack elements.put (document) end feature {NONE} -- Access document: XML_DOCUMENT -- the document that is loaded with the current document builder elements: LINKED_STACK[XML_NODE] -- stack of xml nodes that is used to keep track of the currently "open" xml elements feature -- Events on_start is -- the parsing process has been started => do nothing do end on_start_tag (a_namespace: STRING; a_prefix: STRING; a_local_part: STRING) is -- a start attribute has been encountered => create a new element, add it to the node list -- of the stack's top element and put it on top of the stack local element: XML_ELEMENT do element := document.create_element (a_local_part) elements.item.child_nodes.append (element) elements.put (element) end on_attribute (a_namespace: STRING; a_prefix: STRING; a_local_part: STRING; a_value: STRING) is -- an attribute element has been encountered => create a new attribute and add it to the -- top element's attribute list local attr: XML_ATTRIBUTE do attr := document.create_attribute (a_local_part) attr.set_value (a_value) elements.item.attributes.append (attr) end on_start_tag_finish is -- the end of a start tag has been encountered => do nothing do end on_end_tag (a_namespace: STRING; a_prefix: STRING; a_local_part: STRING) is -- an end tag has been encountered => the current top element on the stack is "closed" and -- can be removed from the stack do elements.remove end on_content (a_content: STRING) is -- an xml text element has been encountered => if the last xml node of the element on top -- of the stack is a text node, append the text to the text node value, otherwise create -- a new text node and add it to the top element's node list local text: XML_CHARACTER_DATA data: STRING cdata: BOOLEAN do -- This is a little hack to avoid the probably stupidest bug in existence in the gobo parser -- (simply take a look at successive values of a_content in the debugger while parsing an xml -- file that contains whitespace to see what I had to put up with) -- Author: Lukas Angerer, 2007-10-09 -- UPDATE: 2007-10-10 -- Altough updating the gobo library and recompiling the project did nothing to solve the problem, -- after the restructuring of the TrucStudio (trucstudio.origo.ethz.ch) repository, the problem -- seems to have disappeared. I leave this "hack" in here since it does no harm and I don't know -- whether the bug is really gone or not. -- Author: Lukas Angerer, 2007-10-10 if a_content /= Void and then not a_content.is_empty and then a_content.item (1) = '%N' then data := "%N" else data := a_content end if data.count = 1 then if data.item (1) = '"' then data.make_from_string (""") elseif data.item (1) = '&' then data.make_from_string ("&") elseif data.item (1) = '%'' then data.make_from_string ("'") elseif data.item (1) = '<' then data.make_from_string ("<") elseif data.item (1) = '>' then data.make_from_string (">") end else if data.has ('"') or else data.has ('&') or else data.has ('%'') or else data.has ('<') or else data.has ('>') then cdata := True end end if not elements.item.child_nodes.is_empty and then (elements.item.child_nodes.last.node_type.is_equal ("XML_TEXT") or elements.item.child_nodes.last.node_type.is_equal ("XML_CDATA_SECTION")) then if cdata and then elements.item.child_nodes.last.node_type.is_equal ("XML_TEXT") then text := document.create_cdata_section (elements.item.child_nodes.last.value) elements.item.child_nodes.replace_child (elements.item.child_nodes.last, text) end elements.item.child_nodes.last.value.append (data) else if cdata then text := document.create_cdata_section (data) else text := document.create_text (data) end elements.item.child_nodes.append (text) end end on_xml_declaration (a_version: STRING; an_encoding: STRING; a_standalone: BOOLEAN) is -- an xml declaration has been encountered => create a new XML_DECLARATION element and set it as the -- document's declaration local decl: XML_DECLARATION do decl := document.create_xml_declaration (a_version, an_encoding) document.child_nodes.append (decl) end on_processing_instruction (a_name: STRING; a_content: STRING) is -- do end end