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的更多相关文章

  1. XPath注入跟SQL注入差不多,只不过这里的数据库走的xml格式

    SQL注入这块不想细聊了,相信很多朋友都听到耳朵长茧,不外乎是提交含有SQL操作语句的信息给后端,后端如果没有做好过滤就执行该语句,攻击者自然可以随意操纵该站点的数据库. 比如有一个图书馆站点book ...

  2. 辅助的写与数据库交互的XML文件的类

    现在企业级WEB应用中与数据库交互的XML文件都是通过插件自动生成的,不过有些时候修改比较老的项目的时候也是需要手动的来做这一动作的!如下代码就是一个实现上述的功能的辅助类,在此记录一下以备后用! p ...

  3. 数据库中操作XML(openXML)

    最近公司项目需要在数据库中操作XML,因此系统的学习了一下 一.openxml的格式 OPENXML( idoc int [ in] , XPathnvarchar [ in ] , [ flags ...

  4. spring security结合数据库验证用户-XML配置方式

    之前的用户信息我们都是使用的内存用户,测试例子可以,实际中使用肯定不行,需要结合数据库进行验证用户.这就是本节的重点: 项目目录如下:  在之前的项目中的依赖中添加两个依赖: <dependen ...

  5. 类似查询mysql数据库的查询XML的JS类

    一个快捷操作XML数据库的Javascript接口对象,包含select.count.tables.fields等方法,能够像操作mysql等其它数据库一样操作XML数据库. if(document. ...

  6. Java数据库编程、XML解析技术

    数据库编程 JDBC概述 是Java Database Connecive,即数据库连接技术的简称,它提供了连接各种常用数据库的能力. 是一种用于执行SQL语句的Java API,可以为多种关系数据库 ...

  7. spring 多线程 写入数据库 和 写入 xml文件

    最近工作中遇到一个需求 多线程先爬取页面 然后将爬取的结果持久化到数据库中 ,一些大文本的内容需要持久化到 xml文件中; 下面是运行后的结果: xml 文件写入结果: 数据库写入结果: 再来张项目结 ...

  8. 数据库数据——>文件xml

    xml文件格式 <smss> <sms> <data> </data> </sms> </smss> 这里面的意思是将数据库里面 ...

  9. Spring Boot 框架下使用MyBatis访问数据库之基于XML配置的方式

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML ...

随机推荐

  1. tp备份数据

    <?php namespace Chenlin2103\Controller; class BaksqlController extends MainController{ public $co ...

  2. java web后台工作原理

    多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http请求的?它们在幕后做了什么动作?Java Servlet API(例如Se ...

  3. Day-01

    昨天学习的内容都是一些简单的入门知识 like:二进制,编程语言这些 我觉得二进制还蛮好玩的 对于ascii码 还好,我不是很陌生 因为学函数的时候,老师有讲到这些 嗯 昨天就这些 继续加油~~~

  4. 今天捡起来python

    时隔多少,我还是要学习,之前懒,结果有些就忘了,用笨方法学Python,码代码夹理解运行改正也就20多分钟,主要是加分习题,你一扩展就要思考的时间长了所以大概要留出1个小时来做他,好了该复习前面的了

  5. OOP跟我来

    世界一切 归于尘土 all is object 两大杀手锏:对象     类 三大武器:封装:继承:多态 #!/usrself=Nonepython # -*- coding: utf-8 -*- # ...

  6. 使用__slots__ __str__ __iter__

    __slots__ 为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性. __str__  用这个命令定义方法,可以返 ...

  7. React Native - 网页组件(WebView)的使用详解

    一.WebView组件介绍 使用 WebView 组件我们可以通过 url 来加载显示一个网页,也可以传入一段 html 代码来显示.下面对其主要属性和方法进行介绍.   1,属性介绍 source: ...

  8. iOS代码块block使用

    代码块的本质是和其他的变量类似,不同的是,代码块存储的数据是一个函数体.使用代码块,你可以像调用其他标准函数一样的调用,可以传入参数,并得到返回值.     脱字符是代码块的语法标记.下图表示代码块的 ...

  9. 2018 ,请领取您Power BI 年终报告

    Power BI365 3Jan 2019 新年已至,岁寒温暖! 为方便Power BI用户们能快速找到所需要的Power BI各类型文章,小悦将2018年Power BI的所有精彩文章按照各应用场景 ...

  10. Linux CPU瓶颈问题分析

    虚线部分为`下一步`的分析方向,图是网络抄的,放这里更容易找