indexing description: "Objects that ..." author: "" date: "$Date$" revision: "$Revision$" class LOCATION_STEP create make, make_root_step feature -- Creation make (step: STRING) is -- local list: LIST[STRING] str_axis, str_node: STRING nt: NODE_TEST do list := split_double_colon (step) str_axis := list.i_th (1) str_node := list.i_th (2) if str_axis.is_equal ("child") then create {AXIS_CHILD} axis elseif str_axis.is_equal ("attribute") then create {AXIS_ATTRIBUTE} axis elseif str_axis.is_equal ("descendant") then create {AXIS_DESCENDANT} axis elseif str_axis.is_equal ("descendant-or-self") then create {AXIS_DESCENDANT_OR_SELF} axis elseif str_axis.is_equal ("ancestor") then create {AXIS_ANCESTOR} axis elseif str_axis.is_equal ("ancestor-or-self") then create {AXIS_ANCESTOR_OR_SELF} axis elseif str_axis.is_equal ("parent") then create {AXIS_PARENT} axis elseif str_axis.is_equal ("self") then create {AXIS_SELF} axis elseif str_axis.is_equal ("following") then create {AXIS_FOLLOWING} axis elseif str_axis.is_equal ("preceding") then create {AXIS_PRECEDING} axis elseif str_axis.is_equal ("following-sibling") then create {AXIS_FOLLOWING_SIBLING} axis elseif str_axis.is_equal ("preceding-sibling") then create {AXIS_PRECEDING_SIBLING} axis else create {AXIS_NONE} axis end create nt.make (str_node) if str_node.is_equal ("node()") then node_test := agent nt.test_node (?) elseif str_node.is_equal ("text()") then node_test := agent nt.test_text (?) else -- default case => simple node name test (for elements and attributes) node_test := agent nt.test_name (?) end end make_root_step is -- creates a 'root' step that accesses the root document of the given node local nt: NODE_TEST do create {AXIS_ROOT} axis create nt.make ("") node_test := agent nt.test_node (?) end feature -- Basic Operations apply (nodes: XML_NODE_LIST) : XML_NODE_LIST is -- do create Result.make (Void) from nodes.start until nodes.off loop from axis.start (nodes.item) until axis.off loop node_test.call ([axis.item]) if node_test.last_result then Result.append (axis.item) end axis.next end nodes.forth end end apply_single (node: XML_NODE; reset: BOOLEAN) : XML_NODE is -- do if reset then axis.start (node) end from until axis.off or Result /= Void loop node_test.call ([axis.item]) if node_test.last_result then Result := axis.item end axis.next end end feature {NONE} -- Access axis: AXIS node_test: FUNCTION[NODE_TEST, TUPLE[XML_NODE], BOOLEAN] feature {NONE} -- Implementation split_double_colon (str: STRING) : LIST[STRING] is -- local l, r: STRING i: INTEGER done: BOOLEAN do create l.make_empty create r.make_empty from i := 1; done := False until done or i >= str.count loop if str.item (i) = ':' and str.item (i+1) = ':' then l := str.substring (1, i-1) r := str.substring (i+2, r.count) end i := i + 1 end if not done then if str.is_empty then l := "descendant-or-self" r := "*" elseif str.is_equal (".") then l := "self" r := "*" elseif str.is_equal ("..") then l := "parent" r := "*" elseif str.item (1) = '@' then l := "attribute" r := str.substring (2, str.count) else l := "child" r := str.twin end end create {ARRAYED_LIST[STRING]} Result.make (2) Result.extend (l) Result.extend (r) end end