0%

TinyXML

文档对象操作

从文件加载

1
2
3
4
5
6
7
8
9
10
11
string fileName;
TiXmlDocument XmlDoc = TiXmlDocument(filename);
if(!XmlDoc.LoadFile()){
if(XmlDoc.Error() == true){
string strErrot = XmlDoc.ErrorDesc(); //错误原因
int iRow = XmlDoc.ErrorRow(); //错误的行
int iCol = XmlDoc.ErrorCol(); //错误的列
LOG_ERROR("XML laod fail reason:%s,row:%d,col:%d",strErrot.c_str(),iRow,iCol);
}
// 加载解析失败 to do ...
}

从字符串中加载

1
2
3
4
5
6
7
8
9
char * cDoc;  // 被解析的字符串
TiXmlDocument XmlDoc;
XmlDoc.Parse(cDoc);
if(XmlDoc.Error() == true){
string strErrot = XmlDoc.ErrorDesc();
int iRow = XmlDoc.ErrorRow();
int iCol = XmlDoc.ErrorCol();
LOG_ERROR("XML parse fail reason:%s,row:%d,col:%d",strErrot.c_str(),iRow,iCol);
}

保存在文件中

1
2
3
4
5
6
7
8
9
10
string fileName;
TiXmlDocument XmlDoc;
//存在其他文件
if(XmlDoc.SaveFile (fileName) == false){
LOG_ERROR("XML save fail fileName:%s",fileName.c_str());
}
//保存在本文件
if(XmlDoc.SaveFile () == false){
LOG_ERROR("XML save fail");
}

保存在字符串中

1
2
3
4
TiXmlDocument XmlDoc;
TiXmlPrinter printer;
XmlDoc.Accept( &printer ); //文档设置观察者
std::string stringBuffer = printer.CStr(); //获取字符串

元素操作

定位到元素

1
2
3
4
5
TiXmlHandle hXmlHandle = TiXmlHandle(&XmlDoc);
TiXmlElement* pElement = hXmlHandle.FirstChild("path1").FirstChild("Item").FirstChild("ElementName").ToElement();
if(!pElement){
LOG_ERROR("%s path error",strElementName.c_str());
}

遍历元素

1
2
3
4
5
TiXmlElement* pElement; // 第一个元素的位置
for(;pElement;\
pElement = pElement->NextSiblingElement("ElementName")){
// 对子元素进行操作pChildElement to do
}

添加元素

1
2
3
4
5
TiXmlElement* pFatherElement; 
TiXmlElement* pXmlChild = pFatherElement->InsertEndChild(TiXmlElement("ElementName"))->ToElement();
if(!pXmlChild){
LOG_ERROR("XML insert fail ");
}

删除元素

1
2
3
4
TiXmlElement* pFatherElement; 
if(pFatherElement->RemoveChild(pFatherElement->FirstChild("ElementName")) == false){
LOG_ERROR("XML remove fail ");
}

元素文本操作

查看元素文本

1
2
3
4
5
6
7
8
9
10
TiXmlElement* pElement; 
string strValue;
for(TiXmlNode *pTextNode = pElement->FirstChild(); \
pTextNode;\
pTextNode = pTextNode->NextSibling()){
if(pTextNode->Type() == TiXmlNode::TINYXML_TEXT){
strValue = pTextNode->ValueStr();//获取到文本
break; //一般是只有一个文本,多个就把break注释掉
}
}

添加元素文本

1
2
TiXmlElement* pElement; 
pElement->InsertEndChild(TiXmlText("123"));

删除元素文本

1
2
3
4
5
6
7
8
9
10
11
TiXmlElement* pElement; 
for(TiXmlNode *pTextNode = pElement->FirstChild(); \
pTextNode;\
pTextNode = pTextNode->NextSibling()){
if(pTextNode->Type() == TiXmlNode::TINYXML_TEXT){
if(!pTextNode->Parent()->RemoveChild(pTextNode)){
LOG_ERROR("XML TEXT remove fail ");
}
break; //一般是只有一个文本,多个就把break注释掉
}
}

修改元素文本

1
2
3
4
5
6
7
8
9
10
TiXmlElement* pElement; 
string strValue;
for(TiXmlNode *pTextNode = pElement->FirstChild(); \
pTextNode;\
pTextNode = pTextNode->NextSibling()){
if(pTextNode->Type() == TiXmlNode::TINYXML_TEXT){
pTextNode->SetValue(strValue);
break; //一般是只有一个文本,多个就把break注释掉
}
}

元素属性

查看元素属性

查数字属性

1
2
3
4
5
6
TiXmlElement* pElement;
string AttrName; //属性名
int iValue = 0;
if(pElement->QueryIntAttribute(AttrName,&iValue) != 0){
LOG_ERROR("Query attribute [%s] fail",AttrName.c_str());
}

查字符串属性

1
2
3
4
5
6
7
TiXmlElement* pElement;
string AttrName; //属性名
string strValue;
if(pElement->QueryStringAttribute(AttrName,&strValue) != 0){
LOG_ERROR("Query attribute [%s] fail",AttrName.c_str());
}

添加与修改元素属性

1
2
3
4
5
6
7
TiXmlElement* pElement;
int iAttrValue; //int 类型属性值
pElement->SetAttribute("AttrName",iAttrValue);

string strAttrValue; //string类型属性值
pElement->SetAttribute("AttrName", strAttrValue);

删除元素属性

1
2
TiXmlElement* pElement;
pXmlElement->RemoveAttribute("AttrName");

XML与TinyXML简介

XML简介

  • XML被设计用来传输和存储数据
  • HTML被设计用来显示数据。
  • XML是一种标记语言,很类似 HTML
  • 标签没有被预定义。您需要自行定义标签
  • XML是树结构,必须要有根元素
  • XML由声明、注释、元素、属性、文本构成

XML语法

  1. 基础语法
  • XML 文档必须有根元素
  • 所有的 XML 元素都必须有一个关闭标签
  • XML 标签对大小写敏感
  • XML 属性值必须加引号
  • 在 XML 中,空格会被保留
  • 所有 XML 文档中的文本均会被解析器解析。只有CDATA区段中的文本会被解析器忽略。
  1. XML声明
    <?xml version=”1.0” encoding=”utf-8”?>

  2. XML中的注释

  3. 实体应用

在 XML 中,一些字符拥有特殊的意义。如果把字符 “<” 放在 XML 元素中,会发生错误

替代符号 原符号 含义
< < less than
> > greater than
& & ampersand
' apostrophe
" quotation mark
  1. XML 以 LF 存储换行

在 Windows 应用程序中,换行通常以一对字符来存储:回车符(CR)和换行符(LF)。
在 Unix 和 Mac OSX 中,使用 LF 来存储新行。

XML元素

  1. 元素可以包含哪些东西
  • 其他元素
  • 文本
  • 属性
  1. 元素的命名规则
  • 名称可以包含字母、数字以及其他的字符名称
  • 不能以数字或者标点符号开始名称
  • 不能以字母 xml(或者 XML、Xml 等等)开始名称
  • 不能包含空格
  1. 最佳命名习惯
  • 建议使用下划线的名称
  • 避免 “-“ 字符。如果您按照这样的方式进行命名:”first-name”,一些软件会认为您想要从 first 里边减去 name。
  • 避免 “.” 字符。如果您按照这样的方式进行命名:”first.name”,一些软件会认为 “name” 是对象 “first” 的属性。
  • 避免 “:” 字符。冒号会被转换为命名空间来使用(稍后介绍)。
  • 使用数据库的命名规则来命名 XML 文档中的元素。
  • 在 XML 中,éòá 等非英语字母是完全合法的,不过需要留意,您的软件供应商不支持这些字符时可能出现的问题。

XML属性

  1. 定义

属性通常提供不属于数据组成部分的信息。在下面的实例中,文件类型与数据无关,但是对需要处理这个元素的软件来说却很重要:

  1. 元素 vs 属性

尽量用元素,元素具有扩展性

TinyXML 文档

英文文档

http://www.grinninglizard.com/tinyxmldocs/index.html

中文文档

https://www.cnblogs.com/flying_bat/archive/2007/11/10/955327.html

文档总结

  1. 使用STL

TinyXML可以被编译成使用或不使用STL,在tinyxml.h的第一行添加”#define TIXML_USE_STL”

  1. 打印输出
  • Print( FILE* ):输出到一个文件流中,包括所有的C文件和标准输出。
  • operator<<:输出到一个c++流中。
  • TiXmlPrinter:输出到一个std::string或者内存缓冲区中。
  1. 句柄

句柄可以直接访问某个节点,无需一层一层的剥开

1
2
3
4
5
TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
}
  1. 行列追踪

TiXmlBase::Row() 和 TiXmlBase::Column() 方法返回结点在源文件中的原始位置。
正确的制表符号可以经由TiXmlDocument::SetTabSize() 来配置。

  1. 使用与安装
    1. Windows项目文件
      • tinyxml: tinyxml 库,非STL
      • tinyxmlSTL: tinyxml 库,STL
        1. Makefile
          • 设置:PROFILE,DEBUG,和TINYXML_USE_STL。
    2. 使用
      • TiXmlDocument 文件
      • TiXmlDeclaration 声明
      • TiXmlComment 注释
      • TiXmlElement 元素
      • TiXmlElement::Attribtutes 元素的属性

TinyXML 常用接口

类列表

类图

  • TiXmlBase
    • TiXmlAttribute
    • TiXmlNode
      • TiXmlComment
      • TiXmlDeclaration
      • TiXmlDocument
      • TiXmlElement
      • TiXmlText
      • TiXmlUnknown
  • TiXmlHandle
  • TiXmlVisitor
    • TiXmlPrinter
作用
TiXmlAttribute 一个属性是一对 name-pair 键值对
TiXmlBase 所有类的基类
TiXmlComment XML注释
TiXmlDeclaration 首行声明
TiXmlDocument XML文件类,可以是真的文件,可以是XML成员
TiXmlElement 元素类
TiXmlHandle 句柄类,可以直接访问某个节点
TiXmlNode 内容的父类
TiXmlPrinter 输出到内存中
TiXmlText XML 文本
TiXmlUnknown 所有无法识别的标记都会存放在unknow中
TiXmlVisitor 实现访问者模式的接口

TiXmlBase

接口 作用
virtual void Print(FILE *cfile, int depth) 输出到文件
int Row() 获取对象所在行
int Column() 获取对象所在列
void SetUserData(void *user)
void *GetUserData()
static void SetCondenseWhiteSpace(bool condense) 是否保留空白
static bool IsWhiteSpaceCondensed() 查看空白设置
static void EncodeString(const TIXML_STRING &str, TIXML_STRING *out) 设置编码格式

TiXmlAttribute (属性)接口

构造接口

接口 作用
TiXmlAttribute(const std::string &_name, const std::string &_value) 还有个const char* 接口

查看接口

接口 作用
const char * Name()
const char* Value()
string ValueStr()
int QueryIntValue(int * _value) 成功 返回 TIXML_SUCCESS,并将结果存在 value中
int QueryDoubleValue(double * _value) 同上

设置接口

接口 作用
void SetName(const char * _name)
void SetValue(const char * _name)
void SetIntValue(const char * _name)
void SetDoubleValue(const char * _name)

其他接口

接口 作用
const TiXmlAttribute*\Next() 下一个属性
const TiXmlAttribute*\Previous() 上一个属性

TiXmlNode 节点

“树访问”接口

接口 作用
TiXmlNode * Parent () 父节点
const TiXmlNode * FirstChild () const 子节点
const TiXmlNode FirstChild (const char \value) const 特定“值”的子节点,有value的都是访问特定值
TiXmlNode * LastChild () 最后一个节点
TiXmlNode LastChild (const char \_value) 特定值得 最后一个节点
const TiXmlNode IterateChildren (const TiXmlNode \previous) 用于遍历 while( child = parent->IterateChildren( child ) )
const TiXmlNode IterateChildren (const char \value, const TiXmlNode *previous) 用于遍历,特定值
const TiXmlNode * PreviousSibling () 前一个兄弟节点
const TiXmlNode PreviousSibling (const char \) const 特定值前一个兄弟节点
const TiXmlNode * NextSibling (const std::string &_value) const 特定值后一个兄弟节点
const TiXmlNode * NextSibling () const 后一个兄弟节点
const TiXmlElement * NextSiblingElement () 后一个兄弟元素
const TiXmlElement NextSiblingElement (const char \) const 后一个兄弟元素
const TiXmlElement * FirstChildElement () const 第一个元素
const TiXmlElement FirstChildElement (const char \_value) const 第一个特定值元素
virtual bool Accept (TiXmlVisitor *visitor) const =0 访问者模式访问

“树操作”接口

接口 作用
TiXmlNode * InsertEndChild (const TiXmlNode &addThis) 尾部插入
TiXmlNode LinkEndChild (TiXmlNode \addThis) 尾部插入

|TiXmlNode InsertBeforeChild (TiXmlNode \beforeThis, const TiXmlNode &addThis)|向前插入
|TiXmlNode InsertAfterChild (TiXmlNode \afterThis, const TiXmlNode &addThis)|向后插入|
|TiXmlNode ReplaceChild (TiXmlNode \replaceThis, const TiXmlNode &withThis)|替换节点|
|bool RemoveChild (TiXmlNode *removeThis)|删除节点|

“节点”操作

接口 作用
void SetValue (const std::string &_value) 设置值,常用于文本设置
const std::string & ValueStr () const 获取值
int Type () const 判断类型
const TiXmlDocument * GetDocument () const
bool NoChildren () const 判断有子节点
virtual TiXmlNode * Clone () const=0 节点复制并返回

格式转换

接口 作用
virtual const TiXmlDocument * ToDocument () const 转文档
virtual const TiXmlElement * ToElement () const 转元素
virtual const TiXmlComment * ToComment () const 转注释
virtual const TiXmlUnknown * ToUnknown () const 转未知
virtual const TiXmlText * ToText () const 转文本
virtual const TiXmlDeclaration * ToDeclaration () const 转属性
TiXmlDeclaration 声明
接口 作用
TiXmlDeclaration (const char *_version, const char *_encoding, const char *_standalone) 有参构造
const char * Version () const 版本
const char * Encoding () const 编码格式
const char * Standalone () const 是否时独立文件
TiXmlDocument 文档

加载与保存文件

接口 作用
TiXmlDocument (const char *documentName) 有参构造
bool LoadFile (TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING) 加载文件,已指定文件
bool SaveFile () const 保存文件,已指定文件
bool LoadFile (const char *filename, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING) 加载文件,未指定文件
bool SaveFile (const char \filename) 保存文件,未指定文件
bool LoadFile (FILE \, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING) 加载文件,根据文件句柄
bool SaveFile (FILE *) const 保存文件,根据文件句柄
void Print () const 输出标准输出中

错误

接口 作用
bool Error () const 是否有错
const char * ErrorDesc () const 错误描述
int ErrorId () const 无用
int ErrorRow () const 错误的行
int ErrorCol () const 错误的列

其他

接口 作用
void SetTabSize (int _tabsize) 设置tab的空格数
const TiXmlElement * RootElement () const 获取跟节点
virtual const char Parse (const char \p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING) 字节流 解析
TiXmlElement 元素

查询属性接口
|接口|作用|
|—-|—-|
|int QueryIntAttribute (const char *name, int *_value) const|int 类型属性,return 0 表示成功,value 为出参
|int QueryDoubleAttribute (const char *name, double *_value) const|double 类型属性
|int QueryFloatAttribute (const char *name, float *_value) const|float 类型属性
|int QueryStringAttribute (const char *name, std::string *_value) const|string 类型属性
|int QueryValueAttribute (const std::string &name, T *outValue) const|自定义类型属性

设置属性接口

接口 作用
void SetAttribute (const char *name, const char *_value) 设置 属性
void SetAttribute (const char *name, int value) 设置int 类型属性
void SetDoubleAttribute (const char *name, double value) 设置 double类型属性

其他接口

接口 作用
TiXmlElement (const char *in_value)
void RemoveAttribute (const std::string &name) 删除属性
const char * GetText () const 读取元素得文本信息
TiXmlText
接口 作用
TiXmlText (const char *initValue)
void SetCDATA (bool _cdata) 设置CDATA
bool CDATA () const 是否设置CDATA

TiXmlHandle 用于快速读取

“树访问”接口

接口 作用
TiXmlHandle (TiXmlNode *_node) 从一个节点获取句柄
const TiXmlNode * FirstChild () const 第一个子节点
const TiXmlNode FirstChild (const char \value) const 第一个特定“值”的子节点
const TiXmlElement * FirstChildElement () const 第一个元素
const TiXmlElement FirstChildElement (const char \_value) const 第一个特定值元素
TiXmlHandle Child (int index) const 定点读取访问子节点
TiXmlHandle Child (const char *value, int index) const 定点读取访问“特定值”的子节点
TiXmlHandle ChildElement (int index) const 定点访问子元素
TiXmlHandle ChildElement (const char *value, int index) const 定点访问“特定值”子元素

格式转换

接口 作用
virtual const TiXmlElement * ToElement () const 转元素
virtual const TiXmlComment * ToComment () const 转注释
virtual const TiXmlUnknown * ToUnknown () const 转未知
virtual const TiXmlText * ToText () const 转文本

注意事项

  • 使用TiXmlElement::GetText()方法,文本必须为第一个子节点(包含注释,注释也是一个节点),否则只用使用TiXmlNode::ValueStr()方法
  • 文本的读取在node类(TiXmlNode::ValueStr())和element类(TiXmlElement::GetText()),文本的设置在node(TiXmlNode::SetValue (const std::string &_value))类中
  • tinyXml 的操作都是指针操作,有插入时,需要注意内存变化