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. sorry

    登录的时候密码忘了 重置了之后才登录上 这是有多久没登录了 好囧呀 近段时间学习Python也断断续续的 马上春节要到了 随后的20多天里 应该更没有时间学习了 想想都很忧伤 明明想很努力来着 但是总 ...

  2. java this关键字的使用

    this关键字 this关键字只能在方法内部使用,表示对"调用方法的那个对象"的引用.      this的三个用法:      1.调用本类中的其他方法        如果在方法 ...

  3. 为什么Python是最适合初创公司的编程语言?

    为什么Python是最适合初创公司的编程语言? 选自Medium 作者:Gleb Pushkov 京东云开发者社区编译 对于初创公司而言,要在众多编程语言中为公司选择一个正确.合适的语言绝非易事. 如 ...

  4. RPC 知识科普一下

    RPC概念及分类 RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”.目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用 ...

  5. Mac 中 PyCharm 配置 Anaconda环境

  6. 关于Unity3D使用时Scene视图清楚,Game视图不清楚的问题

    1.自己不知道什么时候,将LowResolutioinAspectRatios给勾上了, 2.同样的Scale值大于1的时候也会造成模糊,但这个好像比1好发现一点

  7. Java连接Oracle12c

  8. return 返回值

    # ### return 返回值 """ (1) return + 数据类型 : 将这个数据弹到函数的调用处,后面除了可以接六大标准数据类型之外,还可以返回类 对象 函数 ...

  9. 今日bug:error: invalid array assignment

    错误代码: struct STUD { int ID;//学号 ]; float score; }stud; STUD SS[]; student.open("student.dat&quo ...

  10. 如何快速判断一个key是否存在在亿级数据中(bloomFilters)

    面试题 现在有一个非常庞大的数据(亿级),假设全是 int 类型.现在我给你一个数,你需要告诉我它是否存在其中(尽量高效) 分析 采用bloomFilters进行实现(时间&空间尽可能的有效) ...