class EL_XML_DOC_CONTEXT
Client examples: CROSS_PLATFORM_EIFFEL_CONFIGURATION_FILE ; ECF_CLUSTER_INFO ; ECF_INFO ; EIFFEL_CONFIGURATION_FILE ; EIFFEL_CONFIGURATION_LIST ; EIFFEL_PARSING_TEST_SET ; HTTP_CONNECTION_TEST_SET ; JOBSERVE_SEARCHER ; JOBS_RESULT_SET ; MARKUP_ESCAPE_TEST_SET ; MEDIA_ITEM_DEVICE_SYNC_TABLE ; OPEN_OFFICE_TEST_SET ; PYXIS_ECF_CONVERTER ; PYXIS_ECF_PARSER_TEST_SET ; PYXIS_TO_XML_TEST_SET ; RBOX_MANAGEMENT_TASK_TEST_SET ; THUNDERBIRD_EQA_TEST_SET ; VTD_XML_TEST_SET
Top level EL_XPATH_NODE_CONTEXT object representing an XML document
note
description: "Top level ${EL_XPATH_NODE_CONTEXT} object representing an XML document"
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:07:45 GMT (Monday 23rd September 2024)"
revision: "31"
class
EL_XML_DOC_CONTEXT
inherit
EL_XPATH_NODE_CONTEXT
rename
make as make_context,
Token as Token_enum
export
{ANY} Html
undefine
namespace_table
end
EL_LAZY_ATTRIBUTE
rename
item as namespace_table,
new_item as new_namespace_table
end
READABLE_INDEXABLE [INTEGER]
rename
item as token_type,
lower as token_index_lower,
upper as token_index_upper,
valid_index as valid_token_index
redefine
new_cursor
end
EL_ENCODEABLE_AS_TEXT
rename
make as make_encodeable
redefine
make_default
end
EL_CHARACTER_8_CONSTANTS
create
make_from_file, make_from_string, make_from_fragment, make_from_xhtml
convert
make_from_file ({FILE_PATH})
feature {NONE} -- Initialization
make (a_xml_data: EL_STRING_8_POINTER)
--
local
p_root_context: POINTER; type: STRING
do
make_default
if parse_failed then
data := Default_xml_data
if attached {EL_VTD_EXCEPTION} Exception.last_exception as last then
last_exception := last
end
is_namespace_aware := False
else
data := a_xml_data
end
p_root_context := Parser.new_root_context (data, is_namespace_aware)
if is_attached (p_root_context) then
make_context (p_root_context, Current)
create type.make_from_c (c_node_context_encoding_type (p_root_context))
set_encoding_from_name (hyphen.joined (type, c_node_context_encoding (p_root_context).out))
end
rescue
parse_failed := True
retry
end
make_default
do
Precursor
data := Default_xml_data
create file_path
end
make_from_file (a_file_path: FILE_PATH)
--
do
make_default
is_namespace_aware := XML.is_namespace_aware_file (a_file_path)
make (File.raw_plain_text (a_file_path))
file_path.share (a_file_path)
end
make_from_fragment (xml_fragment: READABLE_STRING_8; a_encoding: STRING)
do
make_from_string (new_line.joined (XML.header (1.0, a_encoding).to_latin_1, xml_fragment))
end
make_from_string (a_xml: READABLE_STRING_8)
do
is_namespace_aware := XML.is_namespace_aware (a_xml)
make (create {EL_STRING_8_POINTER}.make (a_xml))
end
make_from_xhtml (xhtml: READABLE_STRING_8)
do
make_from_string (HTML.to_xml (xhtml))
end
feature -- Basic operations
store_as (a_file_path: like file_path)
--
local
l_file: PLAIN_TEXT_FILE
do
create l_file.make_open_write (a_file_path)
l_file.put_managed_pointer (data, 0, data.count)
l_file.close
end
feature -- Token access
new_cursor: EL_DOCUMENT_TOKEN_ITERATOR
do
create Result.make (Current)
Result.start
end
token_string (index: INTEGER): ZSTRING
--
do
Result := wide_string_at_index (index)
end
token_string_32 (index: INTEGER): STRING_32
--
do
Result := wide_string_at_index (index)
end
token_string_8 (index: INTEGER): STRING
--
do
Result := wide_string_at_index (index)
end
token_type (index: INTEGER): INTEGER
-- alias []
do
Result := c_evx_get_token_type (self_ptr, index - 1)
end
feature -- Access
data: EL_STRING_8_POINTER
-- XML character data
file_path: FILE_PATH
last_exception: detachable EL_VTD_EXCEPTION
processing_instruction (a_name: STRING): detachable STRING
-- processing instruction with `a_name' or `Void' if not found
local
pi_name_index: INTEGER
do
across Current as token until attached Result loop
if token.is_processing_instruction_name and then token.item_string_8 ~ a_name then
pi_name_index := token.cursor_index
elseif token.is_processing_instruction and then pi_name_index = (token.cursor_index - 1) then
Result := token.item_string_8
end
end
end
feature -- Measurement
token_depth (index: INTEGER): INTEGER
--
require
valid_index: index >= 1 and index <= token_index_upper
do
Result := c_evx_get_token_depth (self_ptr, index - 1)
end
token_index_lower: INTEGER
do
Result := 1
end
token_index_upper: INTEGER
--
do
Result := c_evx_get_token_count (self_ptr)
end
word_count (exclude_variable_reference: BOOLEAN; included_attributes: EL_STRING_8_LIST): INTEGER
-- count of text words in document and in any `included_attributes'
local
s: EL_ZSTRING_ROUTINES; l_result: ZSTRING
do
create l_result.make_empty
across Current as token loop
if token.is_character_data_item then
Result := Result + s.word_count (token.item_string, True)
elseif token.is_attribute_name then
l_result := token.item_string_8
elseif token.is_attribute and then included_attributes.has (l_result) then
Result := Result + s.word_count (token.item_string, True)
end
end
end
feature -- Status query
is_namespace_aware: BOOLEAN
namespaces_defined: BOOLEAN
-- Are any namespaces defined in document
do
Result := namespace_table.count > 0
end
parse_failed: BOOLEAN
valid_token_index (index: INTEGER): BOOLEAN
do
Result := token_index_lower <= index and index <= token_index_upper
end
feature {EL_DOCUMENT_TOKEN_ITERATOR} -- Implementation
new_namespace_table: EL_HASH_TABLE [STRING, STRING]
local
stage, last_token: INTEGER; s: EL_STRING_8_ROUTINES
do
create Result.make_equal (3)
stage := 1
across Current as token until stage = 3 loop
inspect stage
when 1 then -- start element
stage := stage + token.is_element_open.to_integer
when 2 then -- root element attributes
if token.is_attribute_name_space then
if attached token.item_string_8 as ns_name then
if ns_name ~ XML.xmlns then
Result.put (create {STRING}.make_empty, Default_name)
else
Result.put (create {STRING}.make_empty, s.substring_to_reversed (ns_name, ':'))
end
end
elseif token.is_attribute and last_token = Token_enum.attribute_name_space then
Result.found_item.share (token.item_string_8)
end
stage := stage + token.is_element_close.to_integer
else
end
last_token := token.item
end
end
wide_string_at_index (index: INTEGER): EL_C_WIDE_CHARACTER_STRING
--
require
valid_index: valid_token_index (index)
do
Result := wide_string (c_node_text_at_index (self_ptr, index - 1))
end
feature {NONE} -- Constants
Default_name: STRING = "default"
Default_xml_data: EL_STRING_8_POINTER
once
Result := XML.Default_doc.to_xml
end
Parser: EL_VTD_XML_PARSER
--
once
create Result.make
end
end