1 简介

介绍使用C语言操作xml文件。

使用的开源库:mxml

mxml源码路径:michaelrsweet/mxml: Tiny XML library. (github.com)

mxml官网:Mini-XML (msweet.org)

mxml官方API使用文档:Mini-XML 3.2 API Reference (msweet.org)

2 安装

提前说明:mxml编译之后会生成一个静态库和动态链接库。

首先下载源码压缩包:michaelrsweet/mxml: Tiny XML library. (github.com)

然后解压之后,按照官方网站的说明进行执行。

  1. 配置编译环境
./configure

配置之后,会检查编译环境和配置编译生成的库存放路径,默认放在usr/local中。

如何需要指定库存放路径,可使用如下命令修改:

./configure --prefix=/foo

2)编译

直接运行:

make

编译完成之后会生成:libmxml.so.1.6、libmxml.a、testmxml(测试代码)。

3)将mxml安装到系统库中

执行:

make install

安装之后,使用时包含mxml.h即可。

#include <mxml.h>

在编译程序的使用,可使用 -lmxml 来链接mxml库。

3 测试

使用源文件自带的测试案例进行测试。

编译testmxml.c:

gcc testmxml.c -lmxml -o testxml

运行:

./testxml test.xml

如果运行出现以下错误,表示没找到libmxml.so.1库。

原因:我使用的gcc编译默认使用的是64位的库,也就是/usr/lib64,但是这个库中没有libmxml.so.1

编译的libmxml.so也是一个64位的库:

$ file /usr/local/lib/libmxml.so.1.6
/usr/local/lib/libmxml.so.1.6: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=4e488abf69cf58184b46a03b881e67a5a92c155f, not stripped

解决方式:建立一个软连接,将安装库的路径链接到系统库中。

sudo ln -s /usr/local/lib/libmxml.so.1 /usr/lib64/libmxml.so.1

然后重新执行即可。

4 部分函数介绍

首先先介绍一些基本信息。

4.1 节点

XML文件中的信息都存放在节点中,节点使用mxml_node_t数据结构进行定义,每个节点有个type成员(定义了节点的类型)、可选数据、父节点(parent 上)、子节点(child 下)、兄弟节点(prev 左和next右)。

struct _mxml_node_s			/**** An XML node. ****/
{
mxml_type_t type; /* Node type */
struct _mxml_node_s *next; /* Next node under same parent */
struct _mxml_node_s *prev; /* Previous node under same parent */
struct _mxml_node_s *parent; /* Parent node */
struct _mxml_node_s *child; /* First child node */
struct _mxml_node_s *last_child; /* Last child node */
_mxml_value_t value; /* Node value */
int ref_count; /* Use count */
void *user_data; /* User data */
};

举例说明,有个xml文件格式如下:

<?xml version="1.0" encoding="utf-8"?>
<data>
<node>val1</node>
<node>val2</node>
<node>val3</node>
<group>
<node>val4</node>
<node>val5</node>
<node>val6</node>
</group>
<node>val7</node>
<node>val8</node>
</data>

则其在内存中的节点树关系如下:

?xml version="1.0" encoding="utf-8"?
|
data
|
node - node - node - group - node - node
| | | | | |
val1 val2 val3 | val7 val8
|
node - node - node
| | |
val4 val5 val6

”-“:表示兄弟节点;"|":指向第一个子节点。

4.1.1 节点类型

节点类型数据结构定义如下:

typedef enum mxml_type_e		/**** The XML node type. ****/
{
MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */
MXML_ELEMENT, /* XML element with attributes 节点带属性 */
MXML_INTEGER, /* Integer value 整型值 */
MXML_OPAQUE, /* Opaque string 不透明字符串,不进行字符串分割 */
MXML_REAL, /* Real value 实数 */
MXML_TEXT, /* Text fragment 文本片段 */
MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */
} mxml_type_t;

相关函数:获取节点类型。

mxml_type_t mxmlGetType(mxml_node_t *node);

4.1.2 相关函数

获取第一个子节点:

mxml_node_t *mxmlGetFirstChild(mxml_node_t *node);

获取最后一个子节点:

mxml_node_t *mxmlGetLastChild(mxml_node_t *node);

获取兄弟节点(next右):

mxml_node_t *mxmlGetNextSibling(mxml_node_t *node);

获取兄弟节点(prev 左):

mxml_node_t *mxmlGetPrevSibling(mxml_node_t *node);

获取父节点:

mxml_node_t *mxmlGetParent(mxml_node_t *node);

4.2 创建xml文件并保存

通过实例简述一下如何创建一个XML文件,并保存它。

void creat_xml(void)
{
mxml_node_t *xml; /* <?xml ... ?> */
mxml_node_t *data; /* <data> */
mxml_node_t *node; /* <node> */
mxml_node_t *group; /* <group> */ xml = mxmlNewXML("1.0"); //xml头部 data = mxmlNewElement(xml, "data"); //创建节点<data>,父节点为xml node = mxmlNewElement(data, "node"); //创建节点<note>,父节点为data
mxmlNewText(node, 0, "val1"); //设置节点<note>的值
node = mxmlNewElement(data, "node");
mxmlNewText(node, 0, "val2");
node = mxmlNewElement(data, "node");
mxmlNewText(node, 0, "val3"); group = mxmlNewElement(data, "group"); node = mxmlNewElement(group, "node");
mxmlNewText(node, 0, "val4");
node = mxmlNewElement(group, "node");
mxmlNewText(node, 0, "val5");
node = mxmlNewElement(group, "node");
mxmlNewText(node, 0, "val6"); node = mxmlNewElement(data, "node");
mxmlNewText(node, 1, "val7");
node = mxmlNewElement(data, "node");
mxmlNewText(node, 1, "val8"); //save xml
FILE *fp;
fp = fopen("filename.xml", "w");
mxmlSaveFile(xml, stdout, MXML_NO_CALLBACK);
fclose(fp);
}

对涉及的函数进行简单介绍:

/*
* brife: 新建一个新的XML文档
* para[in] version: Version number to use
* return: 新XML文档父节点
*/
mxml_node_t *mxmlNewXML(const char *version);
/*
* brife: 创建一个新的节点
* para[in] parent: 父节点
* para[in] name: 创建节点名
* return: 新节点
*/
mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
/*
* brife: 创建一个新的节点文本内容
* para[in] parent: 父节点
* para[in] whitespace: 1 = leading whitespace, 0 = no whitespace
* para[in] string: 文本内容
* return: 新节点
*/
mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, const char *string);
/*
* brife: 保存一个xml树到文件中
* para[in] note: xml树节点
* para[in] fp: 写入的文件流指针
* para[in] cb: 空白回调函数,控制保存文件时插入的"空白"字符
* return: 成功返回0,出错返回-1
*/
int mxmlSaveFile(mxml_node_t *node, FILE *fp, mxml_save_cb_t cb);

Linux C操作XML文件的更多相关文章

  1. Asp.Net 操作XML文件的增删改查 利用GridView

    不废话,直接上如何利用Asp.NET操作XML文件,并对其属性进行修改,刚开始的时候,是打算使用JS来控制生成XML文件的,但是最后却是无法创建文件,读取文件则没有使用了 index.aspx 文件 ...

  2. Java操作XML文件 dom4j 篇

    在项目中,我们很多都用到了xml文件,无论是参数配置还是与其它系统的数据交互.今天就来讲一下Java 中使用dom4j来操作XML文件. 我们需要引入的包: //文件包 import java.io. ...

  3. PHP操作XML文件学习笔记

    原文:PHP操作XML文件学习笔记 XML文件属于标签语言,可以通过自定义标签存储数据,其主要作用也是作为存储数据. 对于XML的操作包括遍历,生成,修改,删除等其他类似的操作.PHP对于XML的操作 ...

  4. Qt之QDomDocument操作xml文件-模拟ini文件存储

    一.背景 不得不说Qt是一个很强大的类库,不管是做项目还是做产品,Qt自身封装的东西就已经非常全面了,我们今天的这篇文章就是模拟了Qt读写ini文件的一个操作,当然是由于一些外力原因,我们决定自己来完 ...

  5. JAVA中通过Jaxp操作XML文件基础

    Java中有多种方式操作XML文件,目前讲一讲以SUN公司提供的DocumentBuilderFactory工厂类对象操作XML. 使用XML基本操作就是需要CRUD(增删改查),那么首先通过一个查询 ...

  6. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  7. C#操作xml文件:使用XmlDocument 实现读取和写入

    XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖于内 ...

  8. 利用XmlDocument操作XML文件

    利用XmlDocument可以方便的操作XML文件. .操作XML文件基本方法 ()添加对System.Xml的引用,并使用using语句添加引用: ()假设要读取的XML文件如下: <?xml ...

  9. C#基础知识---Linq操作XML文件

    概述 Linq也就是Language Integrated Query的缩写,即语言集成查询,是微软在.Net 3.5中提出的一项新技术. Linq主要包含4个组件---Linq to Objects ...

  10. C++ 操作XML文件 使用MSXML.DLL

    使用MSXML.DLL读写XML; 文件顶部加入 #import "msxml3.dll"; using namespace MSXML2; //这两句作用是,在程序的文件夹下生成 ...

随机推荐

  1. Flutter笔记 - 事件分发

    事件处理流程 Flutter 事件处理流程主要分两步,为了聚焦核心流程,我们以用户触摸事件为例来说明: 命中测试:当手指按下时,触发 PointerDownEvent 事件,按照深度优先遍历当前渲染( ...

  2. 第二課:Mirth培養興趣之旅 ——由定時刷庫接口編程講起

    1.准备工作 1.1 本机安装vs2019:(https://visualstudio.microsoft.com/zh-hans/) 1.2 本机安装win64的MariaDB 10.3.27版本数 ...

  3. 力扣566(java)-重塑矩阵(简单)

    题目: 在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据. 给你一个由二维数组 mat 表示的  ...

  4. 力扣13(java)-罗马数字转整数(简单)

    题目: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1 ...

  5. HarmonyOS NEXT应用开发案例——列表编辑实现

    介绍 本示例介绍用过使用ListItem组件属性swipeAction实现列表左滑编辑效果的功能. 该场景多用于待办事项管理.文件管理.备忘录的记录管理等. 效果图预览 使用说明: 点击添加按钮,选择 ...

  6. 通过部署流行Web框架掌握Serverless技术

    简介: 通过学习部署流行Web框架,如SpringBoot,Express,Web IDE,让你掌握Serverless函数计算架构和技术,领略弹性并发,高可用的好处.大家好,我是霍大侠,欢迎来到我的 ...

  7. 实时化或成必然趋势?新一代 Serverless 实时计算引擎

    作者:高旸(吾与),阿里巴巴高级产品专家 本文由阿里巴巴高级产品专家高旸(吾与)分享,主要介绍新一代Serverless实时计算引擎的产品特性及核心功能. 一.实时计算 Flink 版 – 产品定位与 ...

  8. 2019-10-31-WPF-设置纯软件渲染

    title author date CreateTime categories WPF 设置纯软件渲染 lindexi 2019-10-31 8:59:2 +0800 2018-04-20 16:36 ...

  9. Echarts立体地图加3D柱图可点击可高亮选中的开发

    注意 echarts请使用v5.1.0以上版本,低版本会无法显示,或者无法触发点击事件. 若有闪屏bug,不要设置temporalSuperSampling属性. 注意图层顺序. 实现原理 借助 ec ...

  10. EasyRepro与测试自动化( 一) 概览

    EasyRepro是一个框架,允许在特定的Dynamics 365组织上执行自动化UI测试.你可以使用它来自动化冒烟测试.回归测试和负载测试等.该框架是由开源项目Selenium构建的,Seleniu ...