CL_DomElement CL_DomElement::get_next_sibling_element() const { CL_DomNode node = get_next_sibling(); while (!node.is_null() && !node.is_element()) node = node.get_next_sibling(); return node.to_element(); }
CL_String CL_DomNode::select_string(const CL_DomString &xpath_expression) const { CL_DomNode node = select_node(xpath_expression); if (node.is_element()) return node.to_element().get_text(); else return node.get_node_value(); }
CL_DomElement CL_DomDocument::get_document_element() { CL_DomNode cur = get_first_child(); while (!cur.is_null()) { if (cur.is_element()) return cur.to_element(); cur = cur.get_next_sibling(); } return CL_DomElement(); }
CL_String CL_DomElement::get_text() const { CL_String str; if (has_child_nodes() == false) return str; CL_DomNode cur = get_first_child(); while (!cur.is_null()) { if (cur.is_text() || cur.is_cdata_section()) str.append(cur.get_node_value()); if (cur.is_element()) str.append(cur.to_element().get_text()); cur = cur.get_next_sibling(); } return str; }
void CL_GUIComponent::load_css_layout(const CL_String &xml_filename, const CL_String &css_filename) { CL_CSSDocument2 css_document; css_document.add_sheet(css_filename); CL_File file(xml_filename); CL_DomDocument dom(file, false); CL_DomNode cur = dom.get_document_element().get_first_child(); std::vector<CL_CSSLayoutElement> element_stack; { CL_DomSelectNode select_node(dom.get_document_element()); impl->css_element.apply_properties(css_document.select(&select_node)); impl->css_element.apply_properties(dom.get_document_element().get_attribute("style")); impl->css_element.set_col_span(dom.get_document_element().get_attribute_int("colspan", 1)); impl->css_element.set_row_span(dom.get_document_element().get_attribute_int("rowspan", 1)); } element_stack.push_back(impl->css_element); while (!cur.is_null()) { CL_CSSLayoutElement child_css_element; if (cur.is_element()) { CL_DomElement cur_element = cur.to_element(); CL_DomSelectNode select_node(cur_element); child_css_element = element_stack.back().create_element(cur_element.get_tag_name()); child_css_element.apply_properties(css_document.select(&select_node)); child_css_element.apply_properties(cur_element.get_attribute("style")); child_css_element.set_col_span(cur_element.get_attribute_int("colspan", 1)); child_css_element.set_row_span(cur_element.get_attribute_int("rowspan", 1)); } else if (cur.is_text()) { CL_DomText cur_text = cur.to_text(); element_stack.back().create_text(cur_text.get_node_value()); } CL_DomNode next = cur.get_first_child(); if (next.is_null()) { next = cur.get_next_sibling(); if (next.is_null()) { next = cur.get_parent_node(); while (!next.is_null() && next.get_next_sibling().is_null()) next = next.get_parent_node(); if (!next.is_null()) next = next.get_next_sibling(); } } else { element_stack.push_back(child_css_element); } cur = next; } CL_GraphicContext gc = get_gc(); impl->css_layout.layout(gc, get_size()); }
CL_Resource CL_ResourceManager::create_resource(const CL_String &resource_id, const CL_String &type) { if (resource_exists(resource_id)) throw CL_Exception(cl_format("Resource %1 already exists", resource_id)); std::vector<CL_String> path_elements = CL_PathHelp::split_basepath(resource_id); CL_String name = CL_PathHelp::get_filename(resource_id); // Walk tree as deep as we can get: CL_DomNode parent = impl->document.get_document_element(); CL_DomNode cur = parent.get_first_child(); std::vector<CL_String>::iterator path_it = path_elements.begin(); while (!cur.is_null() && path_it != path_elements.end()) { if (cur.is_element() && cur.get_namespace_uri() == impl->ns_resources && cur.get_local_name() == "section") { CL_DomElement element = cur.to_element(); CL_String name = element.get_attribute_ns(impl->ns_resources, "name"); if (name == *path_it) { ++path_it; parent = cur; cur = cur.get_first_child(); continue; } } cur = cur.get_next_sibling(); } // Create any missing parent nodes: CL_String prefix = parent.get_prefix(); while (path_it != path_elements.end()) { CL_DomElement section; if (prefix.empty()) { section = impl->document.create_element_ns( impl->ns_resources, (*path_it) ); } else { section = impl->document.create_element_ns( impl->ns_resources,(prefix + ":" + *path_it)); } parent.append_child(section); parent = section; ++path_it; } // Create node: CL_DomElement resource_node; if (prefix.empty()) { resource_node = impl->document.create_element_ns( impl->ns_resources, (type)); } else { resource_node = impl->document.create_element_ns( impl->ns_resources,(prefix + ":" + type)); } resource_node.set_attribute_ns( impl->ns_resources, prefix.empty() ? "name" : (prefix + ":name"), name); parent.append_child(resource_node); // Create resource: impl->resources[resource_id] = CL_Resource(resource_node, *this); return impl->resources[resource_id]; }
std::vector<CL_DomNode> CL_DomDocument::load( CL_IODevice &input, bool eat_whitespace, CL_DomNode insert_point) { clear_all(); CL_XMLTokenizer tokenizer(input); tokenizer.set_eat_whitespace(eat_whitespace); if (insert_point.is_element() == false) insert_point = *this; std::vector<CL_DomNode> node_stack; node_stack.push_back(insert_point); std::vector<CL_DomNode> result; try { CL_XMLToken cur_token; tokenizer.next(&cur_token); while (cur_token.type != CL_XMLToken::NULL_TOKEN) { switch (cur_token.type) { case CL_XMLToken::TEXT_TOKEN: node_stack.back().append_child(create_text_node(cur_token.value)); if (node_stack.back() == insert_point) result.push_back(node_stack.back().get_last_child()); break; case CL_XMLToken::CDATA_SECTION_TOKEN: node_stack.back().append_child(create_cdata_section(cur_token.value)); if (node_stack.back() == insert_point) result.push_back(node_stack.back().get_last_child()); break; case CL_XMLToken::ELEMENT_TOKEN: if (cur_token.variant != CL_XMLToken::END) { CL_DomString namespace_uri = CL_DomDocument_Generic::find_namespace_uri(cur_token.name, cur_token, node_stack.back()); CL_DomElement element = create_element_ns(namespace_uri, cur_token.name); node_stack.back().append_child(element); if (node_stack.back() == insert_point) result.push_back(node_stack.back().get_last_child()); int size = (int) cur_token.attributes.size(); for (int i=0; i<size; i++) { CL_XMLToken::Attribute &attribute = cur_token.attributes[i]; CL_DomString attribute_namespace_uri = CL_DomDocument_Generic::find_namespace_uri(attribute.first, cur_token, node_stack.back()); element.set_attribute_ns( attribute_namespace_uri, attribute.first, attribute.second); } if (cur_token.variant == CL_XMLToken::BEGIN) node_stack.push_back(element); } else { node_stack.pop_back(); if (node_stack.empty()) throw CL_Exception("Malformed XML tree!"); } break; case CL_XMLToken::NULL_TOKEN: break; case CL_XMLToken::ENTITY_REFERENCE_TOKEN: break; case CL_XMLToken::ENTITY_TOKEN: break; case CL_XMLToken::COMMENT_TOKEN: break; case CL_XMLToken::DOCUMENT_TYPE_TOKEN: break; case CL_XMLToken::NOTATION_TOKEN: break; case CL_XMLToken::PROCESSING_INSTRUCTION_TOKEN: break; } tokenizer.next(&cur_token); } } catch (const CL_Exception& e) { for (std::vector<CL_DomNode>::size_type i = 0; i < result.size(); i++) { insert_point.remove_child(result[i]); } throw; } return result; }
CL_DomNode CL_DomDocument::import_node(const CL_DomNode &node, bool deep) { CL_DomNode imported_node; switch (node.get_node_type()) { case NULL_NODE: return imported_node; case ELEMENT_NODE: imported_node = create_element_ns(node.get_namespace_uri(), node.get_node_name()); break; case ATTRIBUTE_NODE: imported_node = create_attribute_ns(node.get_namespace_uri(), node.get_node_name()); imported_node.set_node_value(node.get_node_value()); break; case TEXT_NODE: imported_node = create_text_node(node.get_node_value()); break; case CDATA_SECTION_NODE: imported_node = create_cdata_section(node.get_node_value()); break; case ENTITY_REFERENCE_NODE: imported_node = create_entity_reference(node.get_node_name()); break; case ENTITY_NODE: return imported_node; case PROCESSING_INSTRUCTION_NODE: imported_node = create_processing_instruction(node.to_processing_instruction().get_target(), node.to_processing_instruction().get_data()); break; case COMMENT_NODE: imported_node = create_comment(node.get_node_value()); break; case DOCUMENT_NODE: imported_node = create_document_fragment(); break; case DOCUMENT_TYPE_NODE: return imported_node; case DOCUMENT_FRAGMENT_NODE: imported_node = create_document_fragment(); break; case NOTATION_NODE: return imported_node; } if (node.is_element()) { CL_DomElement import_element = imported_node.to_element(); CL_DomNamedNodeMap node_attributes = node.get_attributes(); int size = node_attributes.get_length(); for (int index = 0; index < size; index++) { CL_DomNode attr = node_attributes.item(index); import_element.set_attribute_node_ns(import_node(attr, deep).to_attr()); } } if (deep) { CL_DomNode cur = node.get_first_child(); while (!cur.is_null()) { imported_node.append_child(import_node(cur, true)); cur = cur.get_next_sibling(); } } return imported_node; }