<PTNOID_ID OID="1" IDDst="1943" IDSrc="0"/>此节点在<LastCrossInfo>节点中,且是多个,我们遍历并读取每个节点的属性值。
class ICallBack
{
static const int AttributeArrayWidth = 5;
static const int LocalNameIndex = 0;
static const int PrefixIndex = 1;
static const int URIIndex = 2;
static const int ValueIndex = 3;
static const int EndIndex = 4;
public:
virtual void startElementLocalName(
const xmlChar* localname,
const xmlChar* prefix,
const xmlChar* URI,
int nb_namespaces,
const xmlChar** namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar** attributes) = 0;
};这里定义了一系列的常量,这个表示的是attributes的结构,attributes一共有五(AttributeArrayWidth)项,分别存储LocalName,Prefix,URI,Value和End字段,没有的字段则为空。static xmlSAXHandler _saxHandlerStruct = {
NULL, /* internalSubset */
NULL, /* isStandalone */
NULL, /* hasInternalSubset */
NULL, /* hasExternalSubset */
NULL, /* resolveEntity */
NULL, /* getEntity */
NULL, /* entityDecl */
NULL, /* notationDecl */
NULL, /* attributeDecl */
NULL, /* elementDecl */
NULL, /* unparsedEntityDecl */
NULL, /* setDocumentLocator */
NULL, /* startDocument */
NULL, /* endDocument */
NULL, /* startElement*/
NULL, /* endElement */
NULL, /* reference */
NULL, /* characters */
NULL, /* ignorableWhitespace */
NULL, /* processingInstruction */
NULL, /* comment */
NULL, /* warning */
NULL, /* error */
NULL, /* fatalError //: unused error() get all the errors */
NULL, /* getParameterEntity */
NULL, /* cdataBlock */
NULL, /* externalSubset */
XML_SAX2_MAGIC, /* initialized */
NULL, /* private */
startElementNsHandler, /* startElementNs */
NULL, /* endElementNs */
NULL, /* serror */
};如上,可以注册很多回调函数,对应不同事件,我们进注册了startElementNsHandler对应 节点开始 这个事件。static void startElementHandler(
void* ctx,
const xmlChar* localname,
const xmlChar* prefix,
const xmlChar* URI,
int nb_namespaces,
const xmlChar** namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar** attributes)
{
ICallBack* pCallback = (ICallBack*)ctx;
pCallback ->startElementLocalName(localname,
prefix, URI, nb_namespaces,
namespaces, nb_attributes,
nb_defaulted, attributes);
} OIDCallBack*pDO = new OIDCallBack();
try
{
xmlDocPtr pDoc =
xmlSAXParseFileWithData(
&_saxHandlerStruct, "PtnScript2_1.xml", 1, pDO);
}
catch (...){
}如上,我们将OIDCallBack的指针传入了xmlSAXParaseFileWithData函数,那么在解析过程中局可以使用此指针了。class OIDCallBack : public ICallBack
{
public:
virtual void startElementLocalName(
const xmlChar* localname,
const xmlChar* prefix,
const xmlChar* URI,
int nb_namespaces,
const xmlChar** namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar** attributes)
{
string sOId, sDId, sSId;
try
{
if (xmlStrcmp(localname, (const xmlChar *)"PTNOID_ID"))
{
return;
}
else
{
for (int i = 0; i < nb_attributes; ++i)
{
if (0 == xmlStrcmp(attributes[ AttributeArrayWidth * i + LocalNameIndex],
(const xmlChar *)"OID"))
{
sOId = string(attributes[ AttributeArrayWidth * i + ValueIndex],attributes[ AttributeArrayWidth * i + EndIndex]);
}
else if (0 == xmlStrcmp(attributes[ AttributeArrayWidth * i + LocalNameIndex],
(const xmlChar *)"IDDst"))
{
sDId = string(attributes[ AttributeArrayWidth * i + ValueIndex],attributes[ AttributeArrayWidth * i + EndIndex]);
}
else if (0 == xmlStrcmp(attributes[ AttributeArrayWidth * i + LocalNameIndex],
(const xmlChar *)"IDSrc"))
{
sSId = string(attributes[ AttributeArrayWidth * i + ValueIndex],attributes[ AttributeArrayWidth * i + EndIndex]);
}
else
{
return;
}
}
}
}
catch (...)
{
return;
}
}
};bool QueryAttributeString(const xmlNodePtr pNode,
const string &sName, string &sAttribute)
{
if (sName.empty())
{
return false;
}
if (NULL == pNode)
{
return false;
}
// 获取节点属性
xmlChar *pChar = xmlGetProp(pNode, (const xmlChar *)sName.c_str());
if (NULL == pChar)
{
return false;
}
sAttribute.assign((const char *)pChar);
// 释放字符串内存
xmlFree(pChar);
return true;
}
void Test_DOMParser()
{
boost::timer oTimer;
oTimer.restart();
int iCount = 0;
try
{
xmlDocPtr pDoc = xmlParseFile("PtnScript2_1.xml");
if (NULL == pDoc)
{
return;
}
xmlNodePtr pRoot = xmlDocGetRootElement(pDoc);
if (NULL == pRoot)
{
return;
}
xmlNodePtr pLastCrossInfo = pRoot->xmlChildrenNode;
// 遍历子节点
bool bFind = false;
while (NULL != pLastCrossInfo)
{
// 比较节点名称
if ((!xmlStrcmp(pLastCrossInfo->name, (const xmlChar *)"LastCrossInfo")))
{
bFind = true;
break;
}
pLastCrossInfo = pLastCrossInfo->next;
}
if (!bFind)
{
return;
}
xmlNodePtr pChild = pLastCrossInfo->xmlChildrenNode;
// 遍历子节点
while (NULL != pChild)
{
// 比较节点名称
if ((!xmlStrcmp(pChild->name, (const xmlChar *)"PTNOID_ID")))
{
string sOId, sDId, sSId;
if (!QueryAttributeString(pChild, "OID", sOId)
|| !QueryAttributeString(pChild, "IDDst", sDId)
|| !QueryAttributeString(pChild, "IDSrc", sSId))
{
break;
}
++iCount;
}
pChild = pChild->next;
}
}
catch (...)
{
return;
}
cout << "Test_DOMParser: " <<
" Node(" << iCount << ") " << oTimer.elapsed() << endl;
cout << endl;
}libxml2的SAX和DOM模式解析文件的效率实测,布布扣,bubuko.com
原文:http://blog.csdn.net/play_fun_tech/article/details/20064397