现在的位置: 首页 > 综合 > 正文

使用Xerces DOM 处理XML文件

2018年05月27日 ⁄ 综合 ⁄ 共 2637字 ⁄ 字号 评论关闭

最近需要处理XML文件,学习了一下Xerces类库。
同其他的XML解析库相比,这个类库比较庞大,功能也相对比较完善。

Xerces C++是其中的C++类库,相对的,还有一个JAVA类库。

使用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 ,j; i < path.size(); ++i){//迭代查找
XMLString::transcode(path[i].c_str(), temp, 256);//内部使用UTF-16编码,所以需要转换
DOMNodeList* childList = root->getChildNodes();//获取所有子节点
for (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();

抱歉!评论已关闭.