Xerces学习


本文翻译自Xerces开发文档,为了能更好理解自行翻译学习,没有完全一一对应。英语不是很好,还望理解。

Using DOM API

Accessing API fromapplication code

 <dom/DOM.hpp> 包含了所有DOM API头文件,所以程序需要#include <xercesc/dom/DOM.hpp>

Class Name

为了防止与程序中其他名称出现冲突,所以DOM类名都以“DOM”作为前缀。如

DOMDocument*   myDocument;
DOMNode*       aNode;
 DOMText*       someText;

Objects Management

程序将使用常规的C++指针访问DOM节点。

DOMNode*       aNode;
   DOMNode* docRootNode;
 
   aNode = someDocument->createElement(anElementName);
   docRootNode = someDocument->getDocumentElement();
   docRootNode->appendChild(aNode);

Memory Management

C++ DOM 提供Release()方法来释放任何由createXXXX工厂方法创建,但已经被“遗弃”的资源。

Objects created byDOMImplementation::createXXXX

用户必须调用release()来释放 任何由DOMImplementation::createXXXX创建的对象。如DOMLSParser,DOMLSSerializer, DOMLSInput, DOMLSOutput, DOMDocument, DOMDocumentType)

访问已经被释放的对象将会引发异常。此外还需要注意以下几点:

1、        当一个DOMDocument 被释放,它的所有子节点和与它相关的子对象(e.g.DOMRange, DOMTreeWalker, DOMNodeIterator or any orphaned nodes)都会被释放。

2、        当一个DOMDocument 被克隆时,克隆出来的document 和原先的document 已经没有关系了,需要显示释放。

3、        当一个DOMDocumentType 被插入到一个DOMDocument 中,因此有了owner,当owner被释放时它也自动被释放。如果自行释放将引发DOMException::INVALID_ACCESS_ERR异常。

Objects created byDOMDocument::createXXXX

用户可以调用release()来释放任何被“遗弃”的节点。当一个节点被释放,它相关的子对象也会被释放。访问一个已经被释放的节点将引发异常。所有的节点最终都将被释放,如果没有被释放,当它的父节点被释放时它也将被释放。

注意:自行释放一个带有父节点的节点将引发DOMException::INVALID_ACCESS_ERR 异常

Objects created byDOMDocumentRange::createRange or DOMDocumentTraversal::createXXXX

用当已经用完了 DOMRange,DOMNodeIterator, DOMTreeWalker.时,需要调用release() 来释放这些对象。

String Type

C++ DOM使用了以空字符结尾的utf-16字符串 (XMLCh *)做为其字符串类型。该字符串来下 (XMLCh *)开销比较小。

所有的字符串数据都将存在于内存中直到document 对象被释放。但是在必要的时候这些字符串数据会被实现重用。用户需要适当的保存返回字符串的副本。

例如,当一个DOMNode被释放之后,为该节点值分配的空间可能会被重用。

DOMDocument*  Createdocument()

{

       XMLCh tempStr[100];

       XMLString::transcode("range", tempStr, 99);

       DOMImplementation* impl =DOMImplementationRegistry::getDOMImplementation(tempStr);

 

       XMLString::transcode("root", tempStr, 99);

       DOMDocument*   doc = impl->createDocument(0, tempStr,0);

       DOMElement*   root = doc->getDocumentElement();

       returndoc;

}

 

void reuseNodeMemory()

{

       DOMDocument* pdoc = Createdocument();

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

 

       DOMText *pAttr =pdoc->createTextNode(xfoo);

       // pAttr hasnode value = "foo"

       // fNodeValuehas "foo"

       pAttr->setNodeValue(xfoo);

       constXMLCh* fNodeValue = pAttr->getNodeValue();

 

       // fNodeValuehas "foo"

       // make a copyof the string for future reference

       XMLCh* oldNodeValue = XMLString::replicate(fNodeValue);

 

       // release thenode pAttr

       pAttr->release();

 

       XMLCh tempStr[100];

       XMLString::transcode("new string", tempStr, 99);

       DOMText *pNewText =pdoc->createTextNode(xfoo);

       pNewText->setNodeValue(tempStr);

       DOMText *pNewText2 =pdoc->createTextNode(xfoo);

       //implementation may have recycled the memory of the pAttr already

       // so it's notsafe to expect fNodeValue still have "foo"

       char *pch= XMLString::transcode(fNodeValue);

       if(XMLString::compareString(xfoo, fNodeValue))

              printf("fNodeValuehas some other content êo%s\n",pch);

 

       // should useyour own safe copy

       if(!XMLString::compareString(xfoo, oldNodeValue))

              printf("Useyour own copy of the oldNodeValue if want to reference the string later\n");

 

       // delete yourown replicated string when done

       XMLString::release(&oldNodeValue);

      

}

Xerces学习_第1张图片发现fNodeValue的值也被改变了。

当调用DOMNode::setNodeValue()设置新值时,实现仅仅是简单的改写了节点的内存,所以之前的指针也将被改写为新的值。这防止DOMNode::setNodeValue()被调用几百次而导致增加内存消耗。

 

voidoverwriteNodeMemory()

{

       DOMDocument* pdoc = Createdocument();

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

       XMLCh xfee[] = {chLatin_f, chLatin_e,chLatin_e, chNull};

 

       // pAttr hasnode value = "foo"

       DOMText *pAttr =pdoc->createTextNode(xfoo);

       pAttr->setNodeValue(xfoo);

       constXMLCh* fNodeValue = pAttr->getNodeValue();

 

       // fNodeValuehas "foo"

       // make a copyof the string for future reference

       XMLCh* oldNodeValue =XMLString::replicate(fNodeValue);

 

       // now setpAttr with a new node value "fee"

       pAttr->setNodeValue(xfee);

 

       // should notrely on fNodeValue for the old node value, it may not compare

       char *pch= XMLString::transcode(fNodeValue);

       if(XMLString::compareString(xfoo, fNodeValue))

       {

              printf("fNodeValuehas some other content êo%s\n",pch);

       }

             

       // should useyour own safe copy

       if(!XMLString::compareString(xfoo, oldNodeValue))

              printf("Useyour own copy of the oldNodeValue if want to reference the string later\n");

 

       // delete yourown replicated string when done

       XMLString::release(&oldNodeValue);

}

fNodeValue的值也被改变了。

你可能感兴趣的:(Xerces)