像使用数据库一样使用xml
xml简介
XML 没什么特别的。它仅仅是纯文本而已。有能力处理纯文本的软件都可以处理 XML。因此其应用范围非常广。不过,能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。##优点XML 简化数据共享在真实的世界中,计算机系统和数据使用不兼容的格式来存储数据。XML 数据以纯文本格式进行存储,因此提供了一种独立于软件和硬件的数据存储方法。这让创建不同应用程序可以共享的数据变得更加容易。XML 简化数据传输通过 XML,可以在不兼容的系统之间轻松地交换数据。对开发人员来说,其中一项最费时的挑战一直是在因特网上的不兼容系统之间交换数据。由于可以通过各种不兼容的应用程序来读取数据,以 XML 交换数据降低了这种复杂性。XML 简化平台的变更升级到新的系统(硬件或软件平台),总是非常费时的。必须转换大量的数据,不兼容的数据经常会丢失。XML 数据以文本格式存储。这使得 XML 在不损失数据的情况下,更容易扩展或升级到新的操作系统、新应用程序或新的浏览器。XML 使您的数据更有用由于 XML 独立于硬件、软件以及应用程序,XML 使您的数据更可用,也更有用。不同的应用程序都能够访问您的数据。
语言结构
通俗的说来,可以将xml的数据看成是一个树状的结构,而树叉上又分布有各种元素,以及其属性值,对于简单应用来说,xml具有一个根节点,根节点下还具有很多级别的节点,我们可以在用节点来存储信息,下面的节点分为节点名称和节点内容以及节点属性等,以下图为例:
根节点为“ModelData”,其下包括子节点“SHPAPE”,其节点下还具有“X”、“Y”、“Z”、“R”的节点,而节点还具有内容,分别为100,50,30,10,“SHPAPE”节点还具有属性值,其“TYPE”属性为“SPHERE”,而“SHPAPE” 的节点值为001;
单单对于这些数据的应用可能一时理不清头绪,下面将使用tinyxml对xml的读写按照数据库的操作来进行使用,就简单的多了。
tinyxml
下载tinyxml
在github上搜索tinyxml,找到相应的版本的库进行下载,这里给出一个网址:https://github.com/leethomason/tinyxml2.git
编程用到的文件为<tinystr.h><tinyxml.h><tinystr.cpp><tinyxml.cpp><tinyxmlerror.cpp><tinyxmlparser.cpp>将这些文件拷贝到自己的工程目录下。
应用实例
(1)在MFC环境下进行测试,首先将上述文件的头文件引用
(2)创建xml文件
// 创建xml文档
TiXmlDocument *pDoc = new TiXmlDocument();
TiXmlDeclaration *pDeclaration = new TiXmlDeclaration( "1.0", "UTF-8", "yes" );
pDoc->LinkEndChild(pDeclaration);
TiXmlElement *pRootNodeA = new TiXmlElement("ModelData");
pDoc->LinkEndChild(pRootNodeA);
//根节点
TiXmlElement *pRootNode = new TiXmlElement("SHPAPE");
pRootNodeA->LinkEndChild(pRootNode);
//设置节点的属性
pRootNode->SetAttribute("TYPE","SPHERE");
//子节点NodeX
TiXmlElement *NodeX = new TiXmlElement("X");
pRootNode->LinkEndChild(NodeX);
//子节点NodeY
TiXmlElement *NodeY = new TiXmlElement("Y");
pRootNode->LinkEndChild(NodeY);
//子节点NodeZ
TiXmlElement *NodeZ = new TiXmlElement("Z");
pRootNode->LinkEndChild(NodeZ);
//子节点NodeR
TiXmlElement *NodeR = new TiXmlElement("R");
pRootNode->LinkEndChild(NodeR);
//设置节点的值
TiXmlText *valueT = new TiXmlText("001");
pRootNode->LinkEndChild(valueT);
//给节点赋值
TiXmlText *valueX= new TiXmlText("100");
NodeX->LinkEndChild(valueX);
TiXmlText *valueY= new TiXmlText("50");
NodeY->LinkEndChild(valueY);
TiXmlText *valueZ= new TiXmlText("30");
NodeZ->LinkEndChild(valueZ);
TiXmlText *valueR= new TiXmlText("10");
NodeR->LinkEndChild(valueR);
pDoc->SaveFile( "C:\\Users\\Desktop\\DesktopChildStation.xml" );
//delete valueT;
delete valueR;
delete valueX;
delete valueY;
delete valueZ;
AfxMessageBox(_T("创建成功"));
(2)添加到xml文件
//打开xml文档
TiXmlDocument *pDoc = new TiXmlDocument("C:\\Users\\Desktop\\DesktopChildStation.xml" );
pDoc->LoadFile();
//获取根节点
TiXmlElement *pRootNodeA = pDoc->RootElement();
//根节点
TiXmlElement *pRootNode = new TiXmlElement("SHPAPE");
pRootNodeA->LinkEndChild(pRootNode);
//设置节点的属性
pRootNode->SetAttribute("TYPE","SPHERE");
//直接在根节点下插入数据
//子节点NodeX
TiXmlElement *NodeX = new TiXmlElement("X");
pRootNode->LinkEndChild(NodeX);
//子节点NodeY
TiXmlElement *NodeY = new TiXmlElement("Y");
pRootNode->LinkEndChild(NodeY);
//子节点NodeZ
TiXmlElement *NodeZ = new TiXmlElement("Z");
pRootNode->LinkEndChild(NodeZ);
//子节点NodeR
TiXmlElement *NodeR = new TiXmlElement("R");
pRootNode->LinkEndChild(NodeR);
//给节点赋值
TiXmlText *valueX= new TiXmlText("5");
NodeX->LinkEndChild(valueX);
TiXmlText *valueY= new TiXmlText("7");
NodeY->LinkEndChild(valueY);
TiXmlText *valueZ= new TiXmlText("9");
NodeZ->LinkEndChild(valueZ);
TiXmlText *valueR= new TiXmlText("11");
NodeR->LinkEndChild(valueR);
pDoc->SaveFile( "C:\\Users\\Desktop\\DesktopChildStation.xml" );
delete valueR;
delete valueX;
delete valueY;
delete valueZ;
AfxMessageBox(_T("增加成功"));
(3)修改xml中的值
TiXmlDocument *pDoc = new TiXmlDocument("C:\\Users\\Desktop\\DesktopChildStation.xml" );
pDoc->LoadFile();
TiXmlElement *pRootNodeA = pDoc->RootElement();
for (TiXmlElement *SphereNode = pRootNodeA->FirstChildElement();SphereNode != NULL;SphereNode = SphereNode->NextSiblingElement())
{
//遍历子节点
for(TiXmlElement *sonElement=SphereNode->FirstChildElement(); sonElement !=NULL;sonElement=sonElement->NextSiblingElement())
{
//全部修改为0
sonElement->Clear();
TiXmlText *pValue = new TiXmlText("0");
sonElement->LinkEndChild(pValue);
}
}
pDoc->SaveFile("C:\\Users\\Desktop\\DesktopChildStation.xml");
AfxMessageBox(_T("修改成功"));
(4)读取xml中的值
//打开xml文档
TiXmlDocument *pDoc = new TiXmlDocument("C:\\Users\\Desktop\\DesktopChildStation.xml" );
pDoc->LoadFile();
TiXmlElement *pRootNodeA = pDoc->RootElement();
CString rootname;
rootname = pRootNodeA->Value();//
AfxMessageBox(rootname);
TiXmlElement *SphereNode = pRootNodeA->FirstChildElement();
rootname = SphereNode->Value();
pRootNodeA->Type();
AfxMessageBox(rootname);
rootname = SphereNode->LastChild()->Value();
AfxMessageBox(rootname);
可以看出,直接使用tinyxml来对xml进行操作是十分繁琐的事情,故可以将其进行进一步的封装,生成符合自己使用习惯的方法。
tinyxml的封装
主要涉及到两个文件,这里直接给出源码
封装源码
(1)xmlOperat.h
#pragma once
#include "afxcmn.h"
#include "stdafx.h"
#include "tinyxml.h"
#include "tinystr.h"
using namespace std;
class xml_user
{
public:
bool Connect(CString InPath);
TiXmlElement* GetRoot();
CString GetLabelName(TiXmlElement* Label);
CString GetLabelData(TiXmlElement* Label);
TiXmlElement* GetLabelByName(TiXmlElement* root,CString Name);
CString GetNodeData(TiXmlElement* root,CString Labelname,CString node);
bool GetLabelExist(TiXmlElement* root,CString LabelName);
void AddLabel(TiXmlElement *parent,CString Labelname,CString LabelData);
void ModifyLabelData(TiXmlElement *parent,CString Labelname,CString LabelData);
void SetAttr(TiXmlElement *Label,CString Attr,CString AttrData);
CString GetAttr(TiXmlElement *Label,CString mType);
TiXmlElement* GetNodeByAttr(TiXmlElement *Root,CString Attr,CString AttrData);
CString* GetChildList(TiXmlElement * parent);
CString Path;
TiXmlDocument *pDoc;
void xml_user::Save();
CString GetAttr(TiXmlElement *parent,CString Label,CString mType);
};
(2)xmlOperate.cpp
#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <afxwin.h>
//#include "UseAdo.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include <string.h>
#include <stdio.h>
#include "xmlOperate.h"
#include "tinyxml.h"
#include "tinystr.h"
using namespace std;
bool xml_user::Connect(CString InPath)
{
CFileFind finder;
bool bResult = finder.FindFile(InPath);
if (bResult == 1)
{ //打开xml文档
string xmlpath = CW2A(InPath.GetString());
pDoc = new TiXmlDocument(xmlpath.data() );
pDoc->LoadFile();
//获取根节点
TiXmlElement *pRoot = pDoc->RootElement();
if (pRoot == NULL)
{
AfxMessageBox(_T("xml连接失败"));
return FALSE;
}
Path = InPath;
return TRUE;
}
else
{
AfxMessageBox(_T("该文件不存在"));
return FALSE;
}
}
void xml_user::Save()
{
string xmlpath =CW2A(Path.GetString());
pDoc->SaveFile(xmlpath.data());
}
//获取根节点
TiXmlElement* xml_user::GetRoot()
{
CFileFind finder;
bool bResult = finder.FindFile(Path);
if (bResult == 1)
{ //打开xml文档
string xmlpath = CW2A(Path.GetString());
pDoc = new TiXmlDocument(xmlpath.data() );
pDoc->LoadFile();
//获取根节点
TiXmlElement *pRoot = pDoc->RootElement();
return pRoot;
}
else
{
AfxMessageBox(_T("该文件不存在"));
return NULL;
}
}
//获取标签的名字
CString xml_user::GetLabelName(TiXmlElement* Label)
{
char temp[100];
sprintf(temp,"%s",Label->Value());
CString LabelName(temp);
return LabelName;
}
//获取标签的数值
CString xml_user::GetLabelData(TiXmlElement* Label)
{
char temp[255];
sprintf(temp,"%s",Label->GetText());
CString LabelName(temp);
return LabelName;
}
//查找标签下的节点的值
CString xml_user::GetNodeData(TiXmlElement* root,CString Labelname,CString node)
{
TiXmlElement *Label = GetLabelByName(root,Labelname);
if (Label == NULL)
{
return NULL;
}
TiXmlElement *hChild = Label->FirstChildElement();
while(hChild != NULL)
{
if (node.Compare(GetLabelName(hChild)) == 0)
{
return GetLabelData(hChild);
}
hChild = hChild->NextSiblingElement();
}
//AfxMessageBox(_T("为找到相应的定义"));
return NULL;
}
//通过标签的内容来查找
TiXmlElement* xml_user::GetLabelByName(TiXmlElement* root,CString Name)
{
TiXmlElement *Level_1 = root->FirstChildElement();
while(Level_1 != NULL)
{
if (Name.Compare(GetLabelName(Level_1)) == 0)
{
return Level_1;
}
else
{
//return GetLabelByName(Level_1,Name);
TiXmlElement *Level_2 = GetLabelByName(Level_1,Name);
if (Level_2 != NULL)
{
return Level_2;
}
else
Level_1 = Level_1->NextSiblingElement();
}
//Level_1 = Level_1->NextSiblingElement();
}
return NULL;
}
//判断标签是否存在
bool xml_user::GetLabelExist(TiXmlElement *root,CString LabelName)
{
if (GetLabelByName(root,LabelName) == NULL)
{
return FALSE;
}
else
return TRUE;
}
//添加节点
void xml_user::AddLabel(TiXmlElement *parent,CString Labelname,CString LabelData)
{
if (LabelData.GetLength() > 0)
{
string lablename = CW2A(Labelname.GetString());
TiXmlElement *pChild = new TiXmlElement(lablename.data());parent->LinkEndChild(pChild);
string labeldata = CW2A(LabelData.GetString());
TiXmlText *Value= new TiXmlText(labeldata.data());pChild->LinkEndChild(Value);
}
else
{
string lablename = CW2A(Labelname.GetString());
TiXmlElement *pChild = new TiXmlElement(lablename.data());parent->LinkEndChild(pChild);
}
Save();
}
//修改节点的值,存在则修改,不存在就创建
void xml_user::ModifyLabelData(TiXmlElement *parent,CString Labelname,CString LabelData)
{
if (GetLabelExist(parent,Labelname))//有的话进行修改
{
TiXmlElement* Label = GetLabelByName(parent,Labelname);
Label->Clear();
string temp =CW2A(LabelData.GetString());
TiXmlText *pValue = new TiXmlText(temp.data());Label->LinkEndChild(pValue);;
}
else
{
AddLabel(parent,Labelname,LabelData);//没有的话进行创建
}
Save();
}
//设置属性
void xml_user::SetAttr(TiXmlElement *Label,CString Attr,CString AttrData)
{
string attr = CW2A(Attr.GetString());
string attrdata = CW2A(AttrData.GetString());
Label->SetAttribute(attr.data(),attrdata.data());
Save();
}
//获取属性
CString xml_user::GetAttr(TiXmlElement *Label,CString mType)
{
string type = CW2A(mType.GetString());
char tempAttr[100];
sprintf(tempAttr,"%s",Label->Attribute(type.data()));
CString Attribution(tempAttr);
return Attribution;
}
//通过属性获得节点
TiXmlElement* xml_user::GetNodeByAttr(TiXmlElement *Root,CString Attr,CString AttrData)
{
TiXmlElement *Level_1 = Root->FirstChildElement();
while(Level_1 != NULL)
{
if (AttrData.Compare(GetAttr(Level_1,Attr)) == 0)
{
return Level_1;
}
else
{
TiXmlElement *Level_2 = GetNodeByAttr(Level_1,Attr,AttrData);
if (Level_2 != NULL)
{
return Level_2;
}
}
Level_1 = Level_1->NextSiblingElement();
}
return NULL;
}
CString* xml_user::GetChildList(TiXmlElement * parent)
{
TiXmlElement *Level_1 = parent->FirstChildElement();
CString ChildNameList[250];
int i = 0;
while(Level_1 != NULL)
{
//AfxMessageBox(GetLabelName(Level_1));
ChildNameList[i] = GetLabelName(Level_1);
i++;
Level_1 = Level_1->NextSiblingElement();
}
return ChildNameList;
}
CString xml_user::GetAttr(TiXmlElement *parent,CString Label,CString mType)
{
TiXmlElement *hChild = GetLabelByName(parent,Label);//
CString name = GetAttr(hChild,mType);
/*AfxMessageBox(name);
CString temp = GetAttr(hChild,mType);*/
return name;
}
实际应用
xml_user p_Record;
p_Record.Connect(xmlpath);
TiXmlElement *Root = p_Record.GetRoot();
CString temp = p_Record.GetNodeData(Root,_T("SPAPE"),_T("X"));//获取x的值
像使用数据库一样使用xml的更多相关文章
- XPath注入跟SQL注入差不多,只不过这里的数据库走的xml格式
SQL注入这块不想细聊了,相信很多朋友都听到耳朵长茧,不外乎是提交含有SQL操作语句的信息给后端,后端如果没有做好过滤就执行该语句,攻击者自然可以随意操纵该站点的数据库. 比如有一个图书馆站点book ...
- 辅助的写与数据库交互的XML文件的类
现在企业级WEB应用中与数据库交互的XML文件都是通过插件自动生成的,不过有些时候修改比较老的项目的时候也是需要手动的来做这一动作的!如下代码就是一个实现上述的功能的辅助类,在此记录一下以备后用! p ...
- 数据库中操作XML(openXML)
最近公司项目需要在数据库中操作XML,因此系统的学习了一下 一.openxml的格式 OPENXML( idoc int [ in] , XPathnvarchar [ in ] , [ flags ...
- spring security结合数据库验证用户-XML配置方式
之前的用户信息我们都是使用的内存用户,测试例子可以,实际中使用肯定不行,需要结合数据库进行验证用户.这就是本节的重点: 项目目录如下: 在之前的项目中的依赖中添加两个依赖: <dependen ...
- 类似查询mysql数据库的查询XML的JS类
一个快捷操作XML数据库的Javascript接口对象,包含select.count.tables.fields等方法,能够像操作mysql等其它数据库一样操作XML数据库. if(document. ...
- Java数据库编程、XML解析技术
数据库编程 JDBC概述 是Java Database Connecive,即数据库连接技术的简称,它提供了连接各种常用数据库的能力. 是一种用于执行SQL语句的Java API,可以为多种关系数据库 ...
- spring 多线程 写入数据库 和 写入 xml文件
最近工作中遇到一个需求 多线程先爬取页面 然后将爬取的结果持久化到数据库中 ,一些大文本的内容需要持久化到 xml文件中; 下面是运行后的结果: xml 文件写入结果: 数据库写入结果: 再来张项目结 ...
- 数据库数据——>文件xml
xml文件格式 <smss> <sms> <data> </data> </sms> </smss> 这里面的意思是将数据库里面 ...
- Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...
随机推荐
- 关于python那些事儿
学习总结: 1.输入一个数据 a=input. 2.在输出结果中增加字符 # 运行如下语句: print("你的名字叫{}.".format("饺子")) (以 ...
- 如何将Excel转换成Markdown表格[转]
在这篇文章中,我将告诉你如何快速的将Excel转换为markdown表格,以及如何将Google Docs,Numbers,网页中的表格或其他类似Excel的程序数据转换为Markdown表格 你可能 ...
- clusterware启动顺序——CRSD
CRSD层面 1.启动过程 )导致">CRSD无法启动集群的应用程序资源的可能原因有:"> 原因:/etc/oracle/ocr.loc指向了错误的OCR文件 [gri ...
- mbstowcs 和ifstream 前为何要setlocale
最近看公司的一些代码,发现一些地方调用了std::locale::global(locale("")); (c++) 和 setlocale(LC_ALL, "" ...
- [Paper][Link note]
http://ieeexplore.ieee.org/document/6974670/
- 按照不规则多边形shp文件分割底层栅格文件tif,统计不同栅格的属性值
我想做到,按照voronoi多边形分割地图土地利用类型文件,统计每个多边形内不同地物的种类和数量.-----如图: 我的第一个想法是:首先用上层多边形将下层栅格图切割开来,然后就可以分别统计栅格内的地 ...
- ssm登录与退出
ssm整合比较好的实例 http://how2j.cn/k/ssm/ssm-tutorial/1137.html?tid=77#nowhere ssm登录后台用户检测(此实例注销有问题):http:/ ...
- cobbler批量化安装系统
- i love my girl
for(int i=0;i<forever;i++) System.out.println("i love my girl!");
- 震惊!!!源程序特征统计程序——基于python getopt库
项目github地址:https://github.com/holidaysss/WC PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟 ...