indexing description: "Handles creating/parsing of an XML document" license: "MIT license (see ../license.txt)" author: "Beat Strasser " date: "$Date$" revision: "$Revision$" class P2P_XML_DOCUMENT inherit P2P_CONSTANTS redefine out end create make_with_root, make_with_jxta_root, make_with_unqualified_root, make_from_root_element, parse_from_string feature {NONE} -- Initialization make_with_root (root_name: STRING; root_namespace: XM_NAMESPACE) is -- Create empty XML document with the root element in the given namespace do create document.make_with_root_named (root_name, root_namespace) is_valid := True end make_with_jxta_root (root_name: STRING) is -- Create empty XML document with a root element in the JXTA namespace do create document.make_with_root_named (root_name, namespace_jxta) is_valid := True end make_with_unqualified_root (root_name: STRING) is -- Create empty document with a root element in the empty namespace do create document.make_with_root_named (root_name, namespace_empty) is_valid := True end make_from_root_element (root: XM_ELEMENT) is -- Create document with given root element do create document.make_with_root_named (root.name, root.namespace) document.set_root_element (root) is_valid := True end parse_from_string (source: STRING) is -- Parse XML document from string require Source_valid: source /= Void local parser: XM_EIFFEL_PARSER stop_on_error_filter: XM_STOP_ON_ERROR_FILTER build_tree_filter: XM_CALLBACKS_TO_TREE_FILTER namespace_resolver_filter: XM_NAMESPACE_RESOLVER do -- create filters create build_tree_filter.make_null create namespace_resolver_filter.set_next (build_tree_filter) create stop_on_error_filter.set_next (namespace_resolver_filter) -- configure parser create parser.make parser.set_callbacks (stop_on_error_filter) -- parse parser.parse_from_string (source) is_valid := parser.is_correct if is_valid then document := build_tree_filter.document end ensure Result_set: is_valid implies document /= Void end feature -- Access document: XM_DOCUMENT last_element: XM_ELEMENT -- Last created element last_content: XM_CHARACTER_DATA -- Last created content data element_by_name (name: STRING): XM_ELEMENT is -- Child element of root node with given name, or Void if not existent local element: XM_ELEMENT do from document.root_element.start until document.root_element.after loop element ?= document.root_element.item_for_iteration if element /= Void and name.is_equal (element.name) then Result := element document.root_element.go_after else document.root_element.forth end end end Xml_header: STRING is "%N" feature -- Status report is_valid: BOOLEAN feature -- Element change create_root_child_element (name: STRING; namespace: XM_NAMESPACE) is -- Create child element of root require Name_valid: name /= Void Namespace_valid: namespace /= Void do create last_element.make_last (document.root_element, name, namespace) ensure Element_set: last_element /= Void and document.root_element.last = last_element end create_content (parent: XM_ELEMENT; content: STRING) is -- Create content for element `parent' require Parent_valid: parent /= Void Content_valid: content /= Void do create last_content.make_last (parent, content) ensure Content_set: last_content /= Void and parent.last = last_content end create_child_element (parent: XM_ELEMENT; name: STRING; namespace: XM_NAMESPACE) is -- Create child element of `parent' require Parent_valid: parent /= Void Name_valid: name /= Void Namespace_valid: namespace /= Void do create last_element.make_last (parent, name, namespace) ensure Element_set: last_element /= Void and parent.last = last_element end add_child_element (parent, child: XM_ELEMENT) is -- Add `child' to `parent' making it the last child do parent.put_last (child) end feature -- Output out: STRING is -- String representation of entire xml document local formatter: XM_FORMATTER output: UC_UTF8_STRING do if is_valid then create output.make_empty create formatter.make formatter.set_output (output) formatter.process_document (document) Result := xml_header + output.out else create Result.make_empty end ensure then Result_set: Result /= Void and (not is_valid implies Result.count = 0) end feature -- Basic operations handle_elements (handler: PROCEDURE [ANY, TUPLE [XM_ELEMENT]]) is -- Call `handler' on each root child element require Document_valid: is_valid Handler_existent: handler /= Void local element: XM_ELEMENT do from document.root_element.start until document.root_element.after loop element ?= document.root_element.item_for_iteration if element /= Void then handler.call ([element]) end document.root_element.forth end end handle_root_attributes (handler: PROCEDURE [ANY, TUPLE [XM_ATTRIBUTE]]) is -- Call `handler' on each attribute of root element require Document_valid: is_valid Handler_existent: handler /= Void local attributes: DS_LIST_CURSOR [XM_ATTRIBUTE] do from attributes := document.root_element.attributes.new_cursor attributes.start until attributes.after loop handler.call ([attributes.item]) attributes.forth end end end