撰写目的只是为了回报IT志愿着
xml文件:ENB-PM~2.xml
<?xml version="1.0" encoding="UTF-8"?>
<PmFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PmFileFormat.xsd">
<FileHeader>
<InfoModelReferenced>PM-V1.0.0</InfoModelReferenced>
<DnPrefix></DnPrefix>
<SenderName>网管</SenderName>
<VendorName>厂商</VendorName>
<JobId></JobId>
<BeginTime>2013-02-25T13:00:00+08:00</BeginTime>
<EndTime>2013-02-25T13:30:00+08:00</EndTime>
</FileHeader>
<Measurements>
<ObjectType>小区测量</ObjectType>
<PmName>
<N i="1" unit="times">eNodeB内DRX状态异频切换出执行次数</N>
<N i="2" unit="times">eNodeB内DRX状态同频切换出成功次数</N>
<N i="3" unit="times">eNodeB内DRX状态同频切换出执行次数</N>
<N i="4" unit="times">eNodeB间DRX状态异频切换出执行次数</N>
<!-- …… 所有指标合集 -->
</PmName>
<PmData>
<Pm Dn="enb29/小区测量/本地小区标识:0" UserLabel="">
<V i="1">0</V>
<V i="2">0</V>
<V i="3">0</V>
<V i="4">0</V>
<!-- …… 所有指标值合集 -->
</Pm>
<Pm Dn="enb29/C小区测量/本地小区标识:2" UserLabel="">
<V i="1">31</V>
<V i="2">31</V>
<V i="3">31</V>
<V i="4">31</V>
<!-- …… 所有指标值合集 -->
</Pm>
</PmData>
</Measurements>
<Measurements>
<ObjectType>基站测量</ObjectType>
<PmName>
<N i="1" unit="times">eNodeB内小区群组异常释放次数</N>
<!-- …… 所有指标值合集 -->
</PmName>
<PmData>
<Pm Dn="enb29/eNodeB测量/基站标识:32" UserLabel="">
<V i="1">0</V>
<!-- …… 所有指标值合集 -->
</Pm>
</PmData>
</Measurements>
</PmFile>
编写代码的目的:生成文件名称位小区测量的文本文件,数据的字段名为 eNodeB内DRX状态异频切换出执行次数、eNodeB内DRX状态同频切换出成功次数、eNodeB内DRX状态同频切换出执行次数、eNodeB间DRX状态异频切换出执行次数。数据为 0,0,0,0 31,31,31,31
代码:文件名:update.cpp
#include <iostream>
#include <string.h>
#include <libxml/parser.h>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
xmlDocPtr doc; //定义解析文档指针
xmlNodePtr curNode; //定义根结点指针(你需要它为了在各个结点间移动)
xmlNodePtr curNodeChild1; //定义第一层结点指针
xmlNodePtr curNodeChild2; //定义第二层结点指针
xmlNodePtr curNodeChild3; //定义第三层节点指针
xmlNodePtr curNodeChild4; //定义第四层节点指针
xmlNodePtr curNodeChild5; //定义第五层节点指针
xmlChar *szKey; //临时字符串变量
char szDocName[] = "../ENB-PM~2.xml"; //待解析文档的路径名
char fileName[50]; //生成的文本文档的名字
fstream file; //声明文件对象
//加载xml文件返回此文档的指针
doc = xmlReadFile(szDocName,"UTF-8",XML_PARSE_RECOVER);
if (NULL == doc)
{
return -1;
}
//获取根节点
curNode = xmlDocGetRootElement(doc);
if (NULL == curNode)
{
xmlFreeDoc(doc);
return -2;
}
//比较节点名字是不是PmFile,寻找目的节点
if (xmlStrcmp(curNode->name, BAD_CAST "PmFile"))
{
xmlFreeDoc(doc);
return -3;
}
//节点指针
curNodeChild1 = curNode->xmlChildrenNode;
//遍历根节点下的子结点
while(curNodeChild1 != NULL)
{
//找到目的结点的名字
if ((!xmlStrcmp(curNodeChild1->name, (const xmlChar *)"Measurements")))
{
curNodeChild2 = curNodeChild1->xmlChildrenNode;
//遍历"Measurements"子结点
while(curNodeChild2 != NULL)
{
//找到"ObjectType"目的结点
if ((!xmlStrcmp(curNodeChild2->name, (const xmlChar *)"ObjectType")))
{
//获得节点的值
szKey = xmlNodeGetContent(curNodeChild2);
//拷贝到数组中,供创建文件名使用
strcpy(fileName, (char*)szKey);
//打开文件,以写和追加的方式打开文件
file.open(fileName,ios::out|ios::app);
//释放字符指针变量
xmlFree(szKey);
//跳到下个结点。因为结点之间有空结点,所以会使用两个next
curNodeChild2 = curNodeChild2->next->next;
//关闭文件
file.close();
//输出文件名,供脚本调用时使用
cout << fileName << ",";
//跳到下次循环,减少不必要的判断次数
continue;
}
//寻找目的结点
if ((!xmlStrcmp(curNodeChild2->name, (const xmlChar *)"PmName")))
{
//以写文件和追加的方式打开文件
file.open(fileName,ios::out|ios::app);
//定义子结点并赋值
curNodeChild4 = curNodeChild2->xmlChildrenNode;
//因为子结点集合的第一个结点不是真正的结点,所以使用next才找到第一个结点
curNodeChild4 = curNodeChild4->next;
//遍历子结点集合
while(curNodeChild4 != NULL)
{
//找到结点名字为N的结点,将结点值以追加的方式写到文件中
if ((!xmlStrcmp(curNodeChild4->name, (const xmlChar *)"N")))
{
szKey = xmlNodeGetContent(curNodeChild4);
file << szKey;
//在结点值之间加上分割符号,因为子结点集合最后有个注释为了出去注释使用4个next,看上去比较丑陋
if(curNodeChild4->next->next->next->next != NULL)
{
file << ",";
}
xmlFree(szKey);
}
curNodeChild4 = curNodeChild4->next->next;
}
curNodeChild2 = curNodeChild2->next->next;
file << endl;
file.close();
continue;
}
//以下注释与上述类似,这里就不多说了
if ((!xmlStrcmp(curNodeChild2->name, (const xmlChar *)"PmData")))
{
file.open(fileName,ios::out|ios::app);
curNodeChild3 = curNodeChild2->xmlChildrenNode;
curNodeChild3 = curNodeChild3->next;
while(curNodeChild3 != NULL)
{
curNodeChild5 = curNodeChild3->xmlChildrenNode;
curNodeChild5 = curNodeChild5->next;
while(curNodeChild5 != NULL)
{
if ((!xmlStrcmp(curNodeChild5->name, (const xmlChar *)"V")))
{
szKey = xmlNodeGetContent(curNodeChild5);
file << szKey;
if(curNodeChild5->next->next->next->next != NULL)
{
file << ",";
}
xmlFree(szKey);
}
curNodeChild5 = curNodeChild5->next->next;
}
curNodeChild3 = curNodeChild3->next->next;
file << endl;
}
curNodeChild2 = curNodeChild2->next->next;
file.close();
continue;
}
curNodeChild2 = curNodeChild2->next->next;
}
//此处跳出循环,代表只取一个"Measurements"结点
break;
}
curNodeChild1 = curNodeChild1->next;
}
return 0;
}
你可能缺库!http://xmlsoft.org/去下载吧
编译命令: g++ -g update.cpp -lxml2 -o update
生成的文件:
注意:文件名可能位乱码,我不知道什么原因
eNodeB内DRX状态异频切换出执行次数,eNodeB内DRX状态同频切换出成功次数,eNodeB内DRX状态同频切换出执行次数,eNodeB间DRX状态异频切换出执行次数
0,0,0,0
31,31,31,31
我主要是为了将xml文件中的数据批量导入oracle数据库,才将其转化为文本数据。