https://blog.csdn.net/lanlicen/article/details/6821585 第一章 什么是XML?1.xml简介XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言)。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。 XML与HTML的设计区别是:XML是用来存储数据的,重在数据本身。而HTML是用来定义数据的,重在数据的显示模式。 简而言之,XML是一个用来存储数据的好东东,具体到我们设备而言,XML可以提供一套标准的、可扩展的存储配置信息的手段。其存储数据的格式是一种树形结构,且必须严格遵守相关的规定。
2.xml语法在XML中,采用了如下的语法: (1) 任何的起始标签都必须有一个结束标签。; (2) 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<tag />。XML解析器会将其翻译成<tag></tag>。; (3) 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如this is a samplestring。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的; (4) 所有的属性都必须有值; (5) 所有的属性都必须在值的周围加上双引号。
下面是两种常见的XML格式: (1)有文本内容: 形如下面<username>root</username>,由于有文本内容,必须将开闭分开写,文本放在中间; <?xml version="1.0"?> <root> //根结点 <mysql> //子结点 <host>127.0.0.1_new_new_new_new</host> //叶子结点 <port>3306</port> <db>test</db> <password>123456</password> <username>root</username> </mysql> </root>
(2)没有文本内容: 形如下面<username user=”admin” />,由于没有文本内容,可以写为一行即可,user=”admin”为属性(PS:建议尽量不要使用属性,而是使用文本内容,具体的原因可参见http://www.w3school.com.cn/xml/xml_attributes.asp中“XML 元素 vs. 属性”小节); <?xml version="1.0"?> <root> <mysql> <host>127.0.0.1_new_new_new_new</host> <port>3306</port> <db>test</db> <password>123456</password> <username user=”admin” /> </mysql> </root>
关于XML更加详细的介绍请看这里:http://www.w3school.com.cn/xml/index.asp
第二章 什么是libxml2?1.libxml2简介Libxml2是一个开源的、C语言的XML程序库,提供了对XML文档的各种操作方法,并且支持XPATH查询,以及部分的支持XSLT转换等功能。 简而言之,libxml2提供一套公共的、便利的操作xml的公共方法(函数)。
2.libxml2的下载和编译(1)libxml2的官方下载地址是ftp://xmlsoft.org/libxml2/,下载最新版libxml2-2.7.8.tar.gz; (2)解压到任意文件夹,并执行下述配置命令: ./configure --host=mips-linux-uclibc CC=mips-linux-uclibc-gcc \ --with-minimum \ --with-xpath \ --with-tree \ --with-writer
说明: --host 表示目标系统是mips-linux-uclibc --CC 表示指定的编译器是mips-linux-uclibc-gcc(需自行将 mips-linux-uclibc-gcc所在的路径加入PATH环境变量中) --with-minimum 表示编译最小系统(嵌入式设备,flash空间有限) --with-xpath 表示编译对xpath的支持 --with-tree 表示对XML树的最基本支持 --with-writer 表示对XML结点的最基本支持
然后执行 make && make install
这样就编译出可以运行在目标平台上的库文件了。同时头文件被放在/usr/local/include/libxml2下,库文件被放在/usr/local/lib下
(为了便于在本机环境中调试,可以使用默认的configure配置即可)
(3)在目标程序的Makefile中加入相应的库文件和头文件路径即可 CC=gcc -Wall -static LIBS=-L /usr/local/lib -lxml2 -lm CFLAGS=-I /usr/local/include/libxml2
testxml: testxml.o $(CC) -o testxml testxml.o $(LIBS)
testxml.o: testxml.c $(CC) -c testxml.c $(CFLAGS)
clean: rm -f *.o testxml
可以通过file命令看到目标程序的类型: [xxx@localhost libxmlTest]$ file testxml testxml: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, statically linked, for GNU/Linux 2.6.9, not stripped
(为了便于在本机调试,上述库文件和目标程序都是使用gcc编译)
注意:编译libxml2的库文件和编译目标程序所使用的编译器必须一致 第四章 关于libxml2的函数库-------------------------------------------------------------------------------------------------- 基本类型 -------------------------------------------------------------------------------------------------- l xmlChar 替代char,使用UTF-8编码的一字节字符串 l xmlDoc 包含由解析文档建立的树结构,xmlDocPtr是指向这个结构的指针。 l xmlNodePtr 和 xmlNode 包含单一结点的结构,xmlNodePtr是指向这个结构的指针,它被用于遍历文档树。
-------------------------------------------------------------------------------------------------- 文档的打开、创建、释放、关闭 -------------------------------------------------------------------------------------------------- l xmlDocPtr doc; //定义文档指针 l doc = xmlNewDoc ("1.0"); //以version = 1.0建立文档 l doc = xmlParseFile(docname); //解析文档,给文档指针赋值(只能以UTF8解析文档) l doc = xmlReadFile(docname,"GB2312",XML_PARSE_RECOVER); //以GB2312编码解析文档 l xmlFreeDoc(doc); //释放解析文档时获取到的内存 l int nRel = xmlSaveFile("xxx.xml",doc); //将文档以默认方式存入一个文件。 l xmlSaveFormatFile (docname, doc, 1); //保存文件到磁盘,第一个参数是写入文件的名,第二个参数是一个xmlDoc结构指针,第三个参数设定为1,保证在输出上写入缩进。 l xmlSaveFormatFileEnc("-", doc, encoding, 1);//将文档以某种编码/格式存入一个文件中。
-------------------------------------------------------------------------------------------------- 结点的增删函数 -------------------------------------------------------------------------------------------------- l xmlNodePtr cur; //定义结点指针 l xmlDocSetRootElement(doc, rootnode);//设置某结点为根结点 l cur = xmlDocGetRootElement(doc); //获取文档根结点 l cur = cur->xmlChildrenNode; //获取结点的子结点 l while (cur != NULL) { //遍历所有的结点 …… cur = cur->next; } l xmlChar *key; key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); //获取文本结点的文本,需用其子结点 l xmlFree(key); //释放xmlNodeListGetString为其返回的字符串分配的内存 l xmlNewTextChild (cur, NULL, "keyword", "123"); //为当前结点添加一个新的子元素文本结点<keyword>123</keyword>,其中NULL是命名空间 l rootnode = xmlNewDocNode(doc, NULL, (const xmlChar*)"root", out);//在doc中创建一个新的结点,名字叫root,文本内容是out指向的字符串 l rootnode = xmlNewNode(NULL, (const xmlChar*)"root");//创建一个新的结点,名字叫root l xmlNodePtr content = xmlNewText((xmlChar *)"NODE CONTENT"); //注意不是xmlNewTextChild() l xmlAddChild(root_node,node);//为root_node添加子结点node l xmlNewChild(root_node, NULL, (xmlChar *) "node1",(xmlChar *) szOut);//为root_node添加子结点node1 l xmlNodeSetContent(curNode, (xmlChar *) "content changed");//设置结点的文本内容 l xmlUnlinkNode(curNode); //将当前结点从文档中断链(unlink),这样本文档就不会再包含这个子结点 l xmlFreeNode(curNode); //手动删除断链结点的内存, 若没有xmlDelNode或者xmlRemoveNode,使用此函数
-------------------------------------------------------------------------------------------------- 结点的属性操作函数 -------------------------------------------------------------------------------------------------- l xmlAttrPtr newattr; newattr = xmlNewProp (newnode, "uri", "123"); //为结点newnode添加属性uri,属性值为123 l if (xmlHasProp(curNode,(xmlChar *)"attribute")) //判断结点curNode是否具有属性attribute l xmlAttrPtr attrPtr = propNodePtr->properties; //属性集是链表 l xmlChar *uri; uri = xmlGetProp(cur, "uri"); //获取属性值 xmlFree(uri); //释放内存 l xmlSetProp(curNode,BAD_(xmlChar *)"attribute", (xmlChar *) "no"); //设置当前结点的attribute属性的属性值为no
-------------------------------------------------------------------------------------------------- XPATH查询函数 -------------------------------------------------------------------------------------------------- l xmlXPathContextPtr context; //XPATH上下文指针 l context = xmlXPathNewContext(doc); //获取context指针 l xmlXPathObjectPtr result;// XPATH对象指针,用来存储查询结果 l result = xmlXPathEvalExpression(xmlChar *xpath, context); //根据条件xpath以及context来进行查询,条件格式:xmlChar *szXpath =(xmlChar *) ("/root/node2[@attribute='yes']"); l xmlXPathFreeContext(context); //释放context内存 l if(xmlXPathNodeSetIsEmpty(result->nodesetval)) //判断查询后的结果是否为空 l xmlNodeSetPtr nodeset; //创建结点集指针 l nodeset = result->nodesetval; //这个结点集对象包含在集合中的元素数目(nodeNr)及一个结点数组(nodeTab)。 l for (i=0; i < nodeset->nodeNr; i++) //遍历结果结点集合 l keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1) l xmlXPathFreeObject (result); //释放内存 l xmlCleanupParser();//清除由libxml2申请的内存 -------------------------------------------------------------------------------------------------- l xmlMalloc是动态分配内存的函数;xmlFree是配套的释放内存函数;xmlStrcmp是字符串比较函数; l 基本上xmlChar字符串相关函数都在xmlstring.h中定义;而动态内存分配函数在xmlmemory.h中定义。
第五章 关于libxml2的查询方式Libxml2查询xml的方式有两种:一种是遍历所有的元素直至找到需要的结点,另外一种是通过XPATH取得特定的元素集合。前者适用于较简单的XML文档,后者类似于通过SQL语句查询关系数据库。由于我们的配置较复杂,因此强烈推荐使用XPATH方式进行查询!
第六章 XPATH简介XPATH可以快速定位到元素结点,而不用去遍历所有元素,其核心的步骤如下: (1) 打开文件; (2) 定义查询语句<类似于SQL语句>; (3) 应用查询语句获得相应的元素集合; (4) 在集合中定位需要的元素; (5) 对元素进行操作<查/插/删/改>; (6) 保存文件;
XPath 使用路径表达式在 XML 文档中选取结点。结点是通过沿着路径或者 step 来选取的。
主要的路径表达式
谓语(Predicates) 谓语用来查找某个特定的节点或者包含某个指定的值的节点。 谓语被嵌在方括号中。
选取未知节点 XPath 通配符可用来选取未知的 XML 元素。
选取若干路径 通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
XPath 运算符 下面列出了可用在 XPath 表达式中的运算符:
以附件中的ZG5000EB500.cfg为例,简单列举几个具体实例(红色部分可能经常被我们所使用):
上述的查询语句已经基本可以满足我们开发中的要求,如果想要更加详细的了解XPATH,请参见下述网址: http://www.w3school.com.cn/xpath/xpath_syntax.asp http://www./xxl/XPathTutorial/General_chi/examples.html 说明 :使用XPATH的实例请参见附件中的源代码
第七章 参考文档http://www.w3school.com.cn/xml/ http://www.w3school.com.cn/xpath/ http://www./xxl/XPathTutorial/General_chi/examples.html libxml目录下的doc文件夹(libxml2-2.7.8\doc)
|
|
来自: XeonGate > 《Ubuntu 16.04.6》