Xerces-C++ DOM编程指南(一)

翻译 2007年09月28日 15:32:00

 原文地址:http://xerces.apache.org/xerces-c/program-dom.html


设计目标
    DOM的C++实现是基于阿帕奇推荐的DOM(Apache Recommended DOM C++ binding).
设计目标是为了满足如下需求:
1.降低内存占用率.
2.提高应用程序的性能,特别是那些服务器类型和多线程的应用程序.
3.多处理系统中优异的延展性.
4.比起Java来其风格更像C++

Xerces-C++对DOM Level 3的支持
Xerces-C++2.8.0包含了W3C DOM(文档对象模型)Level 3的部分实现,此实现是实验性的.详情请查看文档DOM Level 3 Support

使用DOM API
    在您的程序代码中访问API
#include <xercesc/dom/DOM.hpp>
在头文件<dom/DOM.hpp>中,包含了DOM API类所需要的全部头文件

类名
     DOM类名都以“DOM”为前缀(如果类名本身不以“DOM”开头),例如“DOMNode”,这样是为了防止DOM类名与这样一些类名混淆:一些名称可能已经在应用程序或基于DOM的应用程序所必须链接的类中所使用了。
   DOMDocument*   myDocument;
   DOMNode*       aNode;
   DOMText*       someText;

对象管理
     应用程序在C++ DOM中将使用标准C++指针直接访问对象所实现的节点。
思考下面的代码段:
   DOMNode*       aNode;
   DOMNode* docRootNode;
   aNode = someDocument->createElement(anElementName);
   docRootNode = someDocument->getDocumentElement();
   docRootNode->appendChild(aNode);

内存管理
    C++ DOM的实现提供了一个release()方法用来释放所有的通过creatxxx工厂方法创建的“孤儿(即现在已不再使用的)”资源,对象销毁而释放的内存资源由C++ DOM的实现进行管理。更详细说明请查看Apache Recommended DOM C++ binding。

使用DOMImplementation::createXXX创建对象
    用户必须调用release() 函数来释放由DOMImplementation::createXXX创建的现在已经使用完毕的对象,如DOMBuilder, DOMWriter, DOMDocument, DOMDocumentType。
试图访问已经被释放的对象将导致异常行为。
1.当一个DOMDocument对象被释放后,所有与此对象相关的子对象以及其所拥有的对象(如DOMRange, DOMTreeWalker, DOMNodeIterator或任何孤立的节点)也将被释放。
2.当复制一个DOMDocument对象时,这个复制文档对象不再与其父类文档对(original master document)象有任何联系,并且要显示的释放。
3.当一个DOMDocumentType被插入一个DOMDocument后,这个DOMDocumentType也因此有了一个宿主(owner),当它的宿主(owner document)被释放后它也会被自动释放,此时如果释放这个节点时会产生一个DOMException::INVALID_ACCESS_ERR 异常。

使用DOMDocument::createXXX创建对象
    用户应该调用release()函数去显示释放任何一个孤立的节点。当一个孤立节点被释放后,与其相关联的子节点也将被释放。访问一个被释放的节点将导致异常行为。那些孤立的节点最终将会释放,如果现在还没有释放,那么在他们的宿主(owner document)被释放时他们就会被释放。
试图释放一个有父亲的节点将会导致一个DOMException::INVALID_ACCESS_ERR异常。

使用DOMDocumentRange::createRange或者DOMDocumentTraversal::createXXX创建对象
     当DOMRange, DOMNodeIterator, DOMTreeWalker使用完毕后,用户应该调用release()函数。访问一个被释放的对象将导致异常行为。那些对象最终将会释放,如果现在还没有释放,那么在他们的宿主(owner document)被释放时他们就会被释放。
如下有一个例子:
    //
    //  Create a small document tree
    //
    {
        XMLCh tempStr[100];

        XMLString::transcode("Range", tempStr, 99);
        DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(tempStr, 0);
       
        XMLString::transcode("root", tempStr, 99);
        DOMDocument*   doc = impl->createDocument(0, tempStr, 0);
        DOMElement*   root = doc->getDocumentElement();

        XMLString::transcode("FirstElement", tempStr, 99);
        DOMElement*   e1 = doc->createElement(tempStr);
        root->appendChild(e1);

        XMLString::transcode("SecondElement", tempStr, 99);
        DOMElement*   e2 = doc->createElement(tempStr);
        root->appendChild(e2);

        XMLString::transcode("aTextNode", tempStr, 99);
        DOMText*       textNode = doc->createTextNode(tempStr);
        e1->appendChild(textNode);

        //optionally, call release() to release the resource associated with the range after done
        DOMRange* range = doc->createRange();
        range->release();

        //removedElement is an orphaned node, optionally call release() to release associated resource
        DOMElement* removedElement = root->removeChild(e2);
        removedElement->release();

        // no need to release this returned object which is owned by implementation
        XMLString::transcode("*", tempStr, 99);
        DOMNodeList*    nodeList = doc->getElementsByTagName(tempStr);

        // done with the document, must call release() to release the entire document resources
        doc->release();
    };

字符串型别
    C++ DOM使用普通的的无结尾标志的(XMLCh *)UTF-16字符串作为字符串型别,这些(XMLCh*) utf-16 型别的字符串开销极低。
   //C++ DOM
   const XMLCh* nodeValue = aNode->getNodeValue();
所有的字符串数据都将会保存在内存中直到文档对象被销毁。但是像这些字符串数据在执行过程中必要时有可能会被循环利用(RECYCLED),用户应该使用合适的返回字符串副本作为类型安全的引用.
例如当一个DOMNode被释放后,为其分配的内存资源将会被循环在利用。

   XMLCh xfoo[] = {chLatin_f, chLatin_o, chLatin_o, chNull};

   // pAttr has node value = "foo"
   // fNodeValue has "foo"
   pAttr->setNodeValue(xfoo);
   const XMLCh* fNodeValue = pAttr->getNodeValue();

   // fNodeValue has "foo"
   // make a copy of the string for future reference
   XMLCh* oldNodeValue = XMLString::replicate(fNodeValue);

   // release the node pAttr
   pAttr->release()

   // other operations

   // implementation may have recycled the memory of the pAttr already
   // so it's not safe to expect fNodeValue still have "foo"
   if (XMLString::compareString(xfoo, fNodeValue))
       printf("fNodeValue has some other content/n");

   // should use your own safe copy
   if (!XMLString::compareString(xfoo, oldNodeValue))
       printf("Use your own copy of the oldNodeValue if want to reference the string later/n");

   // delete your own replicated string when done
   XMLString::release(&oldNodeValue);

    如果调用DOMNode::setNodeValue() 去设置一个新节点值,执行时仅仅是简单的重写节点值所占用的内存区域,因此先前的指针现在就会自动的指向新的值。用户应该使用合适的先前所返回的字符串副本作为类型安全的引用.例如:
    XMLCh xfoo[] = {chLatin_f, chLatin_o, chLatin_o, chNull};
   XMLCh xfee[] = {chLatin_f, chLatin_e, chLatin_e, chNull};

   // pAttr has node value = "foo"
   pAttr->setNodeValue(xfoo);
   const XMLCh* fNodeValue = pAttr->getNodeValue();

   // fNodeValue has "foo"
   // make a copy of the string for future reference
   XMLCh* oldNodeValue = XMLString::replicate(fNodeValue);

   // now set pAttr with a new node value "fee"
   pAttr->setNodeValue(xfee);

   // should not rely on fNodeValue for the old node value, it may not compare
   if (XMLString::compareString(xfoo, fNodeValue))
       printf("Should not rely on fNodeValue for the old node value/n");

   // should use your own safe copy
   if (!XMLString::compareString(xfoo, oldNodeValue))
       printf("Use your own copy of the oldNodeValue if want to reference the string later/n");

   // delete your own replicated string when done
   XMLString::release(&oldNodeValue);

     这样做是当我们成百上千次调用DOMNode::setNodeValue()时防止内存消耗成等比级数的增长。这一设计容许用户主动的选择返回的字符串应该手动的让它留在内存中还是将这个字符串拷贝到应用程序自己的堆栈中。(这句原文是This design allows users to actively select which returned string should stay in memory by manually copying the string to application's own heap.有些疑问,疑译文是我自己的理解)。

相关文章推荐

基于Dom的C++解析html

采集网页内容时,经常要读取html标签,解析后获取其中的文字信息,Python有BeautifulSoup,javascript可以使用jQuery的find,依靠parent-child关系,id,...
  • tiplip
  • tiplip
  • 2017-04-06 11:55
  • 1100

Xerces-C++ DOM编程指南(二)

XercesDOMParser  构造XercesDOMParser对象  为了用Xerces-C++解析XML文件,利用DOM,您可以创建XercesDOMParser类的一个实例。下面的例子显示了...

Xerces C++ DOM解析XML文档

前一阵子学习Xerces-C++用于解析指定格式XML文档。在这里,把自己的学习经历和大家分享一下,在这里仅仅讲一些入门的知识,希望对大家有所帮助。 Xerces-C++是什么?      Xer...

Xerces-C++ 编程指南

原文:http://xerces.apache.org/xerces-c/program.html     想要使用的独立API ,DOM 、SAX或SAX2, 您的应用程序必须在使用API(由Xer...

XML解析简介及Xerces-C++简单使用举例

XML解析简介及Xerces-C++简单使用举例!

【读书札记】《JavaScript DOM编程指南》

对于Javascript的认识是来自于2011年夏天去实训基地做的一个网页项目,当时认为JavaScript是不是Java的一个派别语言什么的,老师那时候教我们调用了一些Javascript的方法。当...

Aspose.words编程指南之DOM树结构初识,Node类继承关系及说明

转载请注明 http://blog.csdn.net/sinat_30276961/article/details/48136289 上一篇Aspose.words介绍介绍了Aspose.w...

C++ Boost Thread 编程指南

0 前言 标准C++线程即将到来。CUJ预言它将衍生自Boost线程库,现在就由Bill带领我们探索一下Boost线程库。 就在几年前,用多线程执行程序还是一件非比寻常的事。然而今天互联网...

C++ Boost Thread 编程指南

0 前言 标准C++线程即将到来。CUJ预言它将衍生自Boost线程库,现在就由Bill带领我们探索一下Boost线程库。   就在几年前,用多线程执行程序还是一件非比寻常的事。然而今天互联网...

高质量C++/C编程指南(林锐)

版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐     2001-7-1至 2001...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)