像使用数据库一样使用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 ...
随机推荐
- 6 python高级数据处理和可视化
6.2. pyplot作图 1.折线图和散点图 t = np.arange(0,4,0.1) plt.plot(t,t,'o',t,t+2,t,t**2,'o') plt.show() 2.柱线图 p ...
- el和jstl标签库讲解视频
https://www.bilibili.com/video/av22415283/?p=1
- ecplise包的层次结构选择
ecplise包的层次结构选择 平坦方式: 分层方式:
- ftp 发布配置
地址:ftp://192.168.26.128/ 存放文件夹:jenkins
- ubuntu 18.04启动samba图形管理界面
启动samba图形界面管理器出现错误: Failed to load module "canberra-gtk-module" 或 SystemError: could not o ...
- .NET并行计算和并发:Task
任务不是线程. 任务运行的时候需要使用线程,任务并没有取代线程.
- neutron基础一(网络基本命令)基本命令,包括veth peer
ip addr ip link tcpdump -i veth1 -e -v route -n ip route arp ethtool -S veth0 ip link add type veth ...
- windows 10安装docker一直挂起在Installing Components and Removing Files
碰到这个问题百度了好久都没有找到解决方式,什么用管理员方式运行,给文件夹权限啊,都不好使. 后面在bing上面搜docker install compoents关键字找到一条结果,如下如 点进链接,内 ...
- C++编程题#1:含k个3的数
描述 输入二个正整数m 和 k,其中1 < m < 100000,1 < k <5 ,判断m 能否被19整除,且恰好含有k个3,如果满足条件,则输出YES,否则,输出NO. 例 ...
- 安装MySql 8.x版本客户端连接失败解决方案
---恢复内容开始--- 安装完8.0.11MySql数据库及客户端工具Navicat Premium 12(具体安装方法不详细赘述,自行百度,推荐网址:https://blog.csdn.net/c ...