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.有些疑问,疑译文是我自己的理解)。

xerces C/C++ 读取XML文件的一个小例子

main.cpp #include #include #include #include #include #include // Other include ...
  • Jack_Wong2010
  • Jack_Wong2010
  • 2014年04月09日 10:21
  • 3854

Xerces C++ DOM解析XML文档

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

xerces解析器的使用实例详解

#include #include #include #include #include #include #include
  • len_yue_mo_fu
  • len_yue_mo_fu
  • 2017年04月18日 17:33
  • 415

DOM Xerces类库使用方法

DOM Xerces类库使用方法Tuxedo中XML的历史  如今随着XML逐渐成为主流的数据格式之一,自然而然地 Tuxedo将之作为一种基本缓冲类型予以支持。    Tuxedo 7.1 引入了X...
  • zhujun012
  • zhujun012
  • 2011年01月13日 18:26
  • 585

充分利用 Xerces-C++,第 2 部分 (from IBM)

这篇分为两个部分的文章介绍了 Xerces-C++ XML 库。在本第 2 部分中,Rick Parrish 展示了如何装载、操作或者合成一个文档对象模型(DOM)文档,以及如何用可伸缩矢量图形(SV...
  • Feisy
  • Feisy
  • 2008年03月26日 11:55
  • 1323

DOM模型--简单的颜色块显示

这是一个简单的DOm模型的应用: 效果图: a:原始状态: b:点击红色区域之后 c:点击下拉框之后的字体颜色变化 具体的介绍: 这个就是点击上方的颜色块,能够使字体出现不...
  • yangxin_blog
  • yangxin_blog
  • 2015年10月24日 09:20
  • 1574

XML Xerces c++学习笔记--(一)

前面写了个perl的解析器,信息打算存入到XML文件中, 事实证明这可能是个错误的决定。因为当...
  • haoyujie
  • haoyujie
  • 2014年05月09日 10:04
  • 1196

用xerces-c来进行xml schema校验

在xerces-c的官方网站上有文章指引说明是如何进行xml schema校验。http://xerces.apache.org/xerces-c/schema-3.html 给出的例子代码: /...
  • xuzhina
  • xuzhina
  • 2015年07月10日 10:24
  • 2470

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

XML解析简介及Xerces-C++简单使用举例!
  • fengbingchun
  • fengbingchun
  • 2014年09月21日 17:09
  • 8396

xerces-c用DOM方式操作xml

xerces-c是一个可以校验XML合法性的XML解析器,它的语言是C++,它的官方主页:http://xml.apache.org/xerces-c。它支持下面这些标准:XML 1.0 ,XML 1...
  • xuzhina
  • xuzhina
  • 2015年07月09日 11:33
  • 2806
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Xerces-C++ DOM编程指南(一)
举报原因:
原因补充:

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