⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 document.cc

📁 This library provides a C++ interface to XML files. It uses libxml 2 to access the XML files, and in
💻 CC
字号:
/* document.cc * this file is part of libxml++ * * copyright (C) 2003 by the libxml++ development team * * this file is covered by the GNU Lesser General Public License, * which should be included with libxml++ as the file COPYING. */#include <libxml++/document.h>#include <libxml++/dtd.h>#include <libxml++/attribute.h>#include <libxml++/nodes/element.h>#include <libxml++/nodes/entityreference.h>#include <libxml++/nodes/textnode.h>#include <libxml++/nodes/commentnode.h>#include <libxml++/nodes/cdatanode.h>#include <libxml++/nodes/processinginstructionnode.h>#include <libxml++/exceptions/internal_error.h>#include <libxml++/keepblanks.h>#include <libxml++/io/ostreamoutputbuffer.h>#include <libxml/tree.h>#include <assert.h>#include <iostream>namespace{//Called by libxml whenever it constructs something,//such as a node or attribute.//This allows us to create a C++ instance for every C instance.void on_libxml_construct(xmlNode* node){  switch (node->type)  {    case XML_ELEMENT_NODE:    {      node->_private = new xmlpp::Element(node);      break;    }    case XML_ATTRIBUTE_NODE:    {      node->_private = new xmlpp::Attribute(node);      break;    }    case XML_TEXT_NODE:    {      node->_private = new xmlpp::TextNode(node);      break;    }    case XML_COMMENT_NODE:    {      node->_private = new xmlpp::CommentNode(node);      break;    }    case XML_CDATA_SECTION_NODE:    {      node->_private = new xmlpp::CdataNode(node);      break;    }    case XML_PI_NODE:    {      node->_private = new xmlpp::ProcessingInstructionNode(node);      break;    }    case XML_DTD_NODE:    {      node->_private = new xmlpp::Dtd(reinterpret_cast<xmlDtd*>(node));      break;    }    //case XML_ENTITY_NODE:    //{    //  assert(0 && "Warning: XML_ENTITY_NODE not implemented");    //  //node->_private = new xmlpp::ProcessingInstructionNode(node);    //  break;    //}    case XML_ENTITY_REF_NODE:    {      node->_private = new xmlpp::EntityReference(node);      break;    }    case XML_DOCUMENT_NODE:    {      // do nothing ! in case of documents it's the wrapper that is the owner      break;    }    default:    {      // good default for release versions      node->_private = new xmlpp::Node(node);      assert(0 && "Warning: new node of unknown type created");      break;    }  }}//Called by libxml whenever it destroys something//such as a node or attribute.//This allows us to delete the C++ instance for the C instance, if any.void on_libxml_destruct(xmlNode* node){  bool bPrivateDeleted = false;  if (node->type == XML_DTD_NODE)  {    xmlpp::Dtd* cppDtd = static_cast<xmlpp::Dtd*>(node->_private);    if(cppDtd)    {      delete cppDtd;           bPrivateDeleted = true;    }  }  else if (node->type == XML_DOCUMENT_NODE)    // do nothing. See on_libxml_construct for an explanation    ;  else  {    xmlpp::Node* cppNode =  static_cast<xmlpp::Node*>(node->_private);    if(cppNode)    {      delete cppNode;      bPrivateDeleted = true;    }  }  //This probably isn't necessary:  if(bPrivateDeleted)    node->_private = 0;}} //anonymous namespacenamespace xmlpp{Document::Init::Init(){   xmlInitParser(); //Not always necessary, but necessary for thread safety.   xmlRegisterNodeDefault(on_libxml_construct);   xmlDeregisterNodeDefault(on_libxml_destruct);   xmlThrDefRegisterNodeDefault(on_libxml_construct);   xmlThrDefDeregisterNodeDefault(on_libxml_destruct);}Document::Init Document::init_;Document::Document(const std::string& version)  : impl_(xmlNewDoc((const xmlChar*)version.c_str())){  impl_->_private = this;}Document::Document(xmlDoc* doc)  : impl_(doc){  impl_->_private = this;}Document::~Document(){  xmlFreeDoc(impl_);}std::string Document::get_encoding() const{  std::string encoding;  if(impl_->encoding)    encoding = (const char*)impl_->encoding;      return encoding;}Dtd* Document::get_internal_subset() const{  xmlDtd* dtd = xmlGetIntSubset(impl_);  if(!dtd)    return 0;      if(!dtd->_private)    dtd->_private = new Dtd(dtd);      return reinterpret_cast<Dtd*>(dtd->_private);}void Document::set_internal_subset(const std::string& name,                                   const std::string& external_id,                                   const std::string& system_id){  xmlDtd* dtd = xmlCreateIntSubset(impl_,				   (const xmlChar*)name.c_str(),				   external_id.empty() ? (const xmlChar*)NULL : (const xmlChar*)external_id.c_str(),				   system_id.empty() ? (const xmlChar*)NULL : (const xmlChar*)system_id.c_str());             if (dtd && !dtd->_private)    dtd->_private = new Dtd(dtd);}Element* Document::get_root_node() const{  xmlNode* root = xmlDocGetRootElement(impl_);  if(root == 0)    return 0;  else    return reinterpret_cast<Element*>(root->_private);}Element* Document::create_root_node(const std::string& name,                                    const std::string& ns_uri,                                    const std::string& ns_prefix){  xmlNode* node = xmlNewDocNode(impl_, 0, (const xmlChar*)name.c_str(), 0);  xmlDocSetRootElement(impl_, node);  Element* element = get_root_node();  if( !ns_uri.empty() )  {    element->set_namespace_declaration(ns_uri, ns_prefix);    element->set_namespace(ns_prefix);  }  return element;}CommentNode* Document::add_comment(const std::string& content){  xmlNode* node = xmlNewComment((const xmlChar*)content.c_str());  if(!node)    throw internal_error("Cannot create comment node");  xmlAddChild( (xmlNode*)impl_, node);  return static_cast<CommentNode*>(node->_private);}void Document::write_to_file(const std::string& filename, const std::string& encoding){  do_write_to_file(filename, encoding, false);}void Document::write_to_file_formatted(const std::string& filename, const std::string& encoding){  do_write_to_file(filename, encoding, true);}std::string Document::write_to_string(const std::string& encoding){  return do_write_to_string(encoding, false);}std::string Document::write_to_string_formatted(const std::string& encoding){  return do_write_to_string(encoding, true);}void Document::write_to_stream(std::ostream& output, const std::string& encoding){  do_write_to_stream(output, encoding.empty()?get_encoding():encoding, false);}void Document::write_to_stream_formatted(std::ostream& output, const std::string& encoding){  do_write_to_stream(output, encoding.empty()?get_encoding():encoding, true);}void Document::do_write_to_file(    const std::string& filename,    const std::string& encoding,    bool format){  KeepBlanks k(KeepBlanks::Default);  xmlIndentTreeOutput = format?1:0;  int result = 0;  result = xmlSaveFormatFileEnc(filename.c_str(), impl_, encoding.empty()?NULL:encoding.c_str(), format?1:0);  if(result == -1)    throw exception("do_write_to_file() failed.");}std::string Document::do_write_to_string(    const std::string& encoding,    bool format){  KeepBlanks k(KeepBlanks::Default);  xmlIndentTreeOutput = format?1:0;  xmlChar* buffer = 0;  int length = 0;  xmlDocDumpFormatMemoryEnc(impl_, &buffer, &length, encoding.empty()?NULL:encoding.c_str(), format?1:0);  if(!buffer)    throw exception("do_write_to_string() failed.");  // Create a std::string copy of the buffer  std::string result((char*)buffer, length);  // Deletes the original buffer  xmlFree(buffer);  // Return a copy of the string  return result;}void Document::do_write_to_stream(std::ostream& output, const std::string& encoding, bool format){  // TODO assert document encoding is UTF-8 if encoding is different than UTF-8  OStreamOutputBuffer buffer(output, encoding);  xmlSaveFormatFileTo(buffer.cobj(), impl_, encoding.c_str(), format?1:0);}void Document::set_entity_declaration(const std::string& name, XmlEntityType type,                              const std::string& publicId, const std::string& systemId,                              const std::string& content){  xmlAddDocEntity( impl_, (const xmlChar*) name.c_str(), type,     (const xmlChar*) publicId.c_str(), (const xmlChar*) systemId.c_str(),    (const xmlChar*) content.c_str() );}_xmlEntity* Document::get_entity(const std::string& name){  return xmlGetDocEntity(impl_, (const xmlChar*) name.c_str());}} //namespace xmlpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -