class EL_DOCUMENT_EIFFEL_OBJECT_BUILDER
Eiffel object builder from XML/Pyxix node scanning source
note
description: "Eiffel object builder from XML/Pyxix node scanning source"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2024-09-23 8:06:48 GMT (Monday 23rd September 2024)"
revision: "18"
class
EL_DOCUMENT_EIFFEL_OBJECT_BUILDER
inherit
EL_DOCUMENT_NODE_SCAN_SOURCE
rename
seed_object as target,
set_seed_object as set_target
redefine
make_default, set_target, target
end
create
make
feature {NONE} -- Initialisation
make_default
do
create context_stack.make (20)
target := Default_target
Precursor
end
feature {NONE} -- Parsing events
on_comment
--
do
apply_building_action_for_node (last_node)
end
on_content (node: EL_DOCUMENT_NODE_STRING)
--
do
apply_building_action_for_node (node)
end
on_end_document
--
do
context_stack.wipe_out
end
on_end_tag
--
local
popped_context: EL_EIF_OBJ_XPATH_CONTEXT
do
if not context_stack.item.is_xpath_prunable then
popped_context := context_stack.item
context_stack.remove
popped_context.on_context_exit
context_stack.item.on_context_return (popped_context)
end
context_stack.item.remove_xpath_step
end
on_processing_instruction
--
do
apply_building_action_for_node (last_node)
end
on_start_document
--
do
end
on_start_tag
--
local
i, j: INTEGER
do
if attached context_stack.item as top_item then
top_item.set_node (last_node)
top_item.extend_xpath (last_node)
top_item.do_with_xpath
if attached top_item.next_context as next_context then
change_context (next_context)
end
if attached attribute_list.area as area and then area.count > 0 then
from until i = area.count loop
apply_building_action_for_node (area [i])
if attached context_stack.item.next_context as next_context then
change_context (next_context)
from j := 0 until j = area.count loop
if i /= j then
apply_building_action_for_node (area [j])
end
j := j + 1
end
end
i := i + 1
end
end
end
end
feature -- Element change
set_target (a_target: like target)
-- set object to build
local
root_context: EL_EIF_OBJ_ROOT_BUILDER_CONTEXT
table: like Root_context_table
do
Precursor (a_target)
target.set_node (last_node)
table := Root_context_table
if table.has_key (target.root_node_name) then
root_context := Root_context_table.found_item
root_context.set_node (last_node)
else
root_context := new_builder_context (target.root_node_name)
end
context_stack.extend (root_context)
end
feature {NONE} -- Implementation
apply_building_action_for_node (node: EL_DOCUMENT_NODE_STRING)
--
do
if attached context_stack.item as top_item then
top_item.set_node (node)
top_item.extend_xpath (node)
top_item.do_with_xpath
top_item.remove_xpath_step
end
end
change_context (new_context: EL_EIF_OBJ_XPATH_CONTEXT)
--
do
context_stack.item.reset_next_context
context_stack.extend (new_context)
end
new_builder_context (root_node_name: STRING): EL_EIF_OBJ_ROOT_BUILDER_CONTEXT
--
do
create Result.make (root_node_name, target)
end
feature {EL_SMART_BUILDABLE_FROM_NODE_SCAN} -- Internal attributes
context_stack: ARRAYED_STACK [EL_EIF_OBJ_XPATH_CONTEXT]
target: EL_BUILDABLE_FROM_NODE_SCAN
-- target object to build from XML node scan
feature {NONE} -- Constants
Root_context_table: EL_HASH_TABLE [EL_EIF_OBJ_ROOT_BUILDER_CONTEXT, STRING]
--
once
create Result.make (11)
end
Default_target: EL_DEFAULT_BUILDABLE_FROM_NODE_SCAN
once
create Result.make
end
end