CL_DomString CL_DomNode::find_prefix(const CL_DomString &namespace_uri) const { CL_DomElement cur = to_element(); while (!cur.is_null()) { CL_DomNamedNodeMap attributes = cur.get_attributes(); int size = attributes.get_length(); for (int index = 0; index < size; index++) { CL_DomNode attribute = attributes.item(index); if (attribute.get_prefix() == "xmlns" && attribute.get_node_value() == namespace_uri) { return attribute.get_local_name(); } } cur = cur.get_parent_node().to_element(); } return CL_DomString(); }
//рекурсивное клонирование XML-элемента CL_DomElement cloneElement(CL_DomElement &element, CL_DomDocument &doc) { //создаем элемент-клон CL_DomElement clone(doc, element.get_tag_name()); //копируем атрибуты CL_DomNamedNodeMap attributes = element.get_attributes(); unsigned long length = attributes.get_length(); for (unsigned long i = 0; i < length; ++i) { CL_DomNode attr = attributes.item(i); clone.set_attribute(attr.get_node_name(), attr.get_node_value()); } //рекурсивно копируем дочерние элементы for (CL_DomElement child = element.get_first_child_element(); !child.is_null(); child = child.get_next_sibling_element()) clone.append_child(cloneElement(child, doc)); //возвращаем клонированный элемент return clone; }
void CL_DomDocument::save(CL_IODevice &output, bool insert_whitespace) { CL_XMLWriter writer(output); writer.set_insert_whitespace(insert_whitespace); std::vector<CL_DomNode> node_stack; CL_DomNode cur_node = get_first_child(); while (!cur_node.is_null()) { // Create opening node: CL_XMLToken opening_node; opening_node.type = (CL_XMLToken::TokenType) cur_node.get_node_type(); opening_node.variant = cur_node.has_child_nodes() ? CL_XMLToken::BEGIN : CL_XMLToken::SINGLE; opening_node.name = cur_node.get_node_name(); opening_node.value = cur_node.get_node_value(); if (cur_node.is_element()) { CL_DomNamedNodeMap attributes = cur_node.get_attributes(); int length = attributes.get_length(); for (int i = 0; i < length; ++i) { CL_DomAttr attribute = attributes.item(i).to_attr(); opening_node.attributes.push_back( CL_XMLToken::Attribute( attribute.get_name(), attribute.get_value())); } } writer.write(opening_node); // Create any possible child nodes: if (cur_node.has_child_nodes()) { node_stack.push_back(cur_node); cur_node = cur_node.get_first_child(); continue; } // Create closing nodes until we reach next opening node in tree: while (true) { if (cur_node.has_child_nodes()) { CL_XMLToken closing_node; closing_node.type = (CL_XMLToken::TokenType) cur_node.get_node_type(); closing_node.name = cur_node.get_node_name(); closing_node.variant = CL_XMLToken::END; writer.write(closing_node); } cur_node = cur_node.get_next_sibling(); if (!cur_node.is_null()) break; if (node_stack.empty()) break; cur_node = node_stack.back(); node_stack.pop_back(); } } }