您的位置:首页 > 其它

使用Xerces DOM 处理XML文件

2015-06-26 10:16 447 查看
Xerces C++是其中的C++类库,相对的,还有一个JAVA类库。同其他的XML解析库相比,这个类库比较庞大,功能也相对比较完善。

使用Xerces中DOM的相关流程为:

1.初始化Xerces

使用Xerces编程,必须在调用其他的Xerces API之前,使用XMLPlatformUtils::Initialize() 来初始化。

以下为文档中相关内容:

XMLPlatformUtils::Initialize() and XMLPlatformUtils::Terminate must be called at least once in each process.

You are allowed to call XMLPlatformUtils::Initialize() and XMLPlatformUtils::Terminate multiple times, but each call to XMLPlatformUtils::Initialize() must be matched with a call to XMLPlatformUtils::Terminate.

2.生成解析器XercesDOMParser对象,然后将要处理的XML文件地址传递给这个对象。这个对象的作用是对XML进行解析,然后生成一棵树。在生成树之前,还可以设置一些参数,这些参数将对解析器的行为产生影响。

具体如何设置参数,可以查阅手册。如果对XML比较熟悉,这些参数的含义都是可以直接猜出来的。

以下为一个典型的过程:

m_DOMParser = new XercesDOMParser();

m_DOMParser->setValidationScheme(XercesDOMParser::Val_Always);

m_ERRHandler = (ErrorHandler*)new HandlerBase();

m_DOMParser->setErrorHandler(m_ERRHandler);

try{

m_DOMParser->parse("test.xml");

}

catch(const XMLException& toCatch) {

return false;

}

当解析器对象对XML文件解析完毕后,就生成了一棵树。

这个树中的每个节点,都对应一个XML文件中的基本组成部分。

目前这些节点的具体类型有:

enum NodeType {

ELEMENT_NODE = 1,

ATTRIBUTE_NODE = 2,

TEXT_NODE = 3,

CDATA_SECTION_NODE = 4,

ENTITY_REFERENCE_NODE = 5,

ENTITY_NODE = 6,

PROCESSING_INSTRUCTION_NODE = 7,

COMMENT_NODE = 8,

DOCUMENT_NODE = 9,

DOCUMENT_TYPE_NODE = 10,

DOCUMENT_FRAGMENT_NODE = 11,

NOTATION_NODE = 12

};

在Xerces中基本上所有这些类型的父类都是DOMNode。

其中TEXT_NODE为每个类型为ELEMENT_NODE的节点所对应的值,比如<NAME>abc</NAME>中NAME 这个节点将有一个子节点类型为TEXT_NODE,他的值为abc。

3.查找某个ELEMENT的方法

习惯了使用.NET中XmlDocument的人,可能习惯了使用SelectNodes这种直接通过ELEMENT来查找的方式。

很遗憾,Xerces中好像没有提供类似的方法,XPATH好像也没有完全实现。需要自己来层级遍历。

在实现时应该注意编码问题。

查找某个ELEMENT所对应的值的方法:

比如

<level1>

<level2>

<name>abc</name>

</level2>

</level1>

vector<string> path;

//这里为查找某个ELEMENT的路径;要查找name,则该path[0] ="level1";path[1]="level2";path[2]="name"

XMLCh temp[257];

DOMNode *root = m_DOMParser->getDocument();//取得了整个树的根节点

for (int i = 0 ; i < path.size(); ++i){//迭代查找

XMLString::transcode(path[i].c_str(), temp, 256);//内部使用UTF-16编码,所以需要转换

DOMNodeList* childList = root->getChildNodes();//获取所有子节点

for (int j = 0; j < childList->getLength(); ++j){

if (childList->item(j)->getNodeType() == DOMNode::ELEMENT_NODE

&& XMLString::compareString(childList->item(j)->getNodeName(), temp) == 0){

root = childList->item(j);

break;

}

}

if (j == childList->getLength())

return false;

}

char *tv = XMLString::transcode(root->getFirstChild()->getNodeValue());

//每个ELEMENT的第一子节点为TEXT_NODE

//tv=="abc",

XMLString::release(&tv);

4.在对XML操作完后,需要delete相关对象,最后调用XMLPlatformUtils::Terminate();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: