c语言解析XML文件

c语言解析XML文件
c语言解析XML文件

XML文件的解析--libxml库函数解释[转]

libxml(一)

摘要

Libxml是一个有免费许可的用于处理XML、可以轻松跨越多个平台的C语言库。这个指南提供它的基本函数的例子。

绪论

Libxml是一个实现读、创建及操纵XML数据功能的C语言库。这个指南提供例子代码并给出它基本功能的解释。在这个项目的主页上有Libxml及更多关于它可用的资料。包含有完整的API文档。这个指南并不能替代这些完整的文档,但是阐明功能需要使用库来完成基本操作。

这个指南基于一个简单的XML应用,它使用我写的一篇文章生成,它包含有元数据和文章的主体。

本指南中的例子代码示范如何做到:

? 解析文档

? 取得指定元素的文本

? 添加一个元素及它的内容

? 添加一个属性

? 取得一个属性的值

例子的完整代码包含在附录中

数据类型

Libxml定义了许多数据类型,我们将反复碰到它们,它隐藏了杂乱的来源以致你不必处理它除非你有特定的需要。xmlChar 替代char,使用UTF-8编码的一字节字符串。如果你的数据使用其它编码,它必须被转换到UTF-8才能使用libxml的函数。在libxml编码支持WEB页面有更多关于编码的有用信息。XmlDoc 包含由解析文档建立的树结构,xmlDocPtr是指向这个结构的指针。

xmlNodePtr and xmlNode 包含单一结点的结构xmlNodePtr是指向这个结构的指针,它被用于遍历文档树。

解析文档

解析文档时仅仅需要文件名并只调用一个函数,并有错误检查。完整代码:附录C, Keyword例程代码

①xmlDocPtr doc;

②xmlNodePtr cur;

③doc = xmlParseFile(docname);

④if (doc == NULL ) {

fprintf(stderr,"Document not parsed successfully. \n");

return;

}

⑤cur = xmlDocGetRootElement(doc);

⑥if (cur == NULL) {

fprintf(stderr,"empty document\n");

xmlFreeDoc(doc);

return;

}

⑦if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {

fprintf(stderr,"document of the wrong type, root node != story");

xmlFreeDoc(doc);

return;

}

①定义解析文档指针。

②定义结点指针(你需要它为了在各个结点间移动)。

④检查解析文档是否成功,如果不成功,libxml将指一个注册的错误并停止。

注释

一个常见错误是不适当的编码。XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存。如果文档是这样,libxml将自动地为你转换到UTF-8。更多关于XML编码信息包含在XML标准中。

⑤取得文档根元素

⑥检查确认当前文档中包含内容。

⑦在这个例子中,我们需要确认文档是正确的类型。―Story‖是在这个指南中使用文档的根类型。

取得元素内容

你找到在文档树中你要查找的元素后可以取得它的内容。在这个例子中我们查找―story‖元素。进程将在冗长的树中查找我们感兴趣的元素。我们假定期你已经有了一个名为doc的xmlDocPtr和一个名为cur的xmlNodPtr。

①cur = cur->xmlChildrenNode;

②while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){

parseStory (doc, cur);

}

cur = cur->next;

}

①取得cur的第一个子结点,cur指向文档的根,即―story‖元素。

②这个循环迭代通过―story‖的子元素查找―storyinfo‖。这是一个包含有我们将查找的―keywords‖的元素。它使用了libxml字符串比较函数xmlStrcmp。如果相符,它调用函数parseStory。

void

parseStory (xmlDocPtr doc, xmlNodePtr cur) {

xmlChar *key;

① cur = cur->xmlChildrenNode;

②while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"keyword"))) {

③ key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);

printf("keyword: %s\n", key);

xmlFree(key);

}

cur = cur->next;

}

return;

}

①再次取得第一个子结点。

②像上面那个循环一样,我们能过迭代,查找我们感兴趣的叫做―keyword‖的元素。

③当我们找到元素―keyword‖时,我们需要打印它包含在XML中的记录的内容,文本被包含于元素的子结点中,因此我们借助了cur->xmlChildrenNode,为了取得文本,我们使用函数xmlNodeListGetString,它有一个文档指针参数,在这个例子中,我们仅仅打印它。

注释

因为xmlNodeListGetString为它返回的字符串分配内存,你必须使用xmlFree释放它。

使用XPath取得元素内容

除了一步步遍历文档树查找元素外,Libxml2包含支持使用Xpath表达式取得指定结点集。完整的Xpath API文档在这里。Xpath允许通过路径文档搜索匹配指定条件的结点。在下面的例子中,我们搜索文档中所有的―keyword‖元素。

注释

下面是Xpath完整的讨论。它详细的使用资料,请查阅Xpath规范。

这个例子完整的代码参见附录D,XPath例程代码。

Using XPath requires setting up an xmlXPathContext and then supplying the XPath expression and the context to the xmlXPathEvalExpression

function.

The function returns an xmlXPathObjectPtr, which includes the set of nodes satisfying the XPath expression.

使用XPath需要安装xmlXPathContext才支持XPath表达式及xmlXPathEvalExpression函数,这个函数返回一个xmlXPathObjectPtr,它包含有

XPath表达式的结点集。

xmlXPathObjectPtr

getnodeset (xmlDocPtr doc, xmlChar *xpath){

①xmlXPathContextPtr context;

xmlXPathObjectPtr result;

②context = xmlXPathNewContext(doc);

③result = xmlXPathEvalExpression(xpath, context);

④if(xmlXPathNodeSetIsEmpty(result->nodesetval)){

printf("No result\n");

return NULL;

}

xmlXPathFreeContext(context);

return result;

}

①首先定义变量

②初始化变量context

③应用XPath表达式

④检查结果

由函数返回的xmlPathObjectPtr包含一个结点集和其它需要被迭代及操作的信息。在这个例子中我们的函数返回xmlXPathObjectPtr,我们使用它打印我们文档中keyword结点的内容。这个结点集对象包含在集合(nodeNr)中的元素数目及一个结点(nodeTab)数组。

①for (i=0; i < nodeset->nodeNr; i++) {

②keyword = xmlNodeListGetString(doc,

nodeset->nodeTab[i]->xmlChildrenNode, printf("keyword: %s\n", keyword);

xmlFree(keyword);

}

①变量nodeset->Nr持有结点集中元素的数量。我们使用它遍历数组。

②打印每个结点包含的内容。

注释

Note that we are printing the child node of the node that is returned, because the contents of the keyword element are a child text node.注意我们打印的是结点的子结点的返回值,因为keyword 元素的内容是一个子文本结点。

写元素

写元素内容使用上面许多一样的步骤—解析文档并遍历树。我们先解析文档然后遍历树查找我们想插入元素的位置。在这个例子中,我们再一次查找―storyinfo

‖元素并插入一个keyword。然后我们装文件写入磁盘。完整代码:附录E,添加keyword例程

本例中主要的不同在于parseStory

void

parseStory (xmlDocPtr doc, xmlNodePtr cur, char *keyword) {

①xmlNewTextChild (cur, NULL, "keyword", keyword);

return;

}

①XmlNewTextChild函数添加一个当前结点的新的子元素到树中

一旦结点被添加,我们应当写文档到文件中。你是否想给元素指定一个命名空间?你能添加它,在我们的例子中,命名空间是NULL。

xmlSaveFormatFile (docname, doc, 1);

第一个参数是写入文件的名,你注意到和我们刚刚读入的文件名是一样的。在这个例子中,我们仅仅覆盖原来的文件。第二个参数是一个xmlDoc结构指针,第三个参数设定为1,保证在输出上写入。

libxml(二)

写属性

写属性类似于给一个新元素写文本。在这个例子中,我们将添加一个reference结点URI属性到我们的文档中。完整代码:附录F,添加属性例程代码。reference是story元素的一个子结点,所以找到并插入新元素及其属性是简单的。一旦我们在parseDoc进行了错误检查,我们将在正确的位置加放我们的新元素。但进行之前我们需要定义一个此前我们不见过的数据类型。

xmlAttrPtr newattr;

我们也需要xmlNodePtr:

xmlNodePtr newnode;

剩下的parseDoc则和前面一样,检查根结点是否为story。如果是的,那我们知道我们将在指定的位置添加我们的元素。

① newnode = xmlNewTextChild (cur, NULL, "reference", NULL);

②newattr = xmlNewProp (newnode, "uri", uri);

①使用xmlNewTextChild函数添国一个新结点到当前结点位置。

一旦结点被添加,文件应像前面的例子将我们添加的元素及文本内容写入磁盘。

取得属性

取得属性值类似于前面我们取得一个结点的文本内容。在这个例子中,我们将取出我们在前一部分添加的URI的值。完整代码:附录G,取得属性值例程代码。

这个例子的初始步骤和前面是类似的:解析文档,查找你感兴趣的元素,然后进入一个函数完成指定的请求任务。在这个例子中,我们调用getReference。

void

getReference (xmlDocPtr doc, xmlNodePtr cur) {

xmlChar *uri;

cur = cur->xmlChildrenNode;

while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"reference"))) {

① uri = xmlGetProp(cur, "uri");

printf("uri: %s\n", uri);

xmlFree(uri);

}

cur = cur->next;

}

return;

}

①关键函数是xmlGetProp,它返回一个包含属性值的xmlChar。在本例中,我们仅仅打印它。

注释

如果你使用DTD定义属性的固定值或缺省值,这个函数也将取得它。

编码转换

数据编码兼容问题是程序员新建普通的XML或特定XML时最常见的困难。按照这里

稍后的讨论来思考设计你的应用程序将帮助你避免这个困难。实际上,libxml能以UTF-8格式保存和操纵多种数据

你的程序使用其它的数据格式,比如常见的ISO-8859-1编码,必须使用libxml函数转换到UTF-8。如果你想你的程序以除UTF-8外的其它编码方式输出也必须做转换。

如果能有效地转换数据Libxml将使用转换器。无转换器时,仅仅UTF-8、UTF-16和ISO-8859-1能够被作为外部格式使用。有转换器时,它能将从其它格式与UTF-8互换的任何格式均可使用。当前转换器支持大约150种不同的编码格式之间的相互转换。实际支持的格式数量正在被实现。每一个实现在的转换器尽可能的支持每一种格式。

警告

一个常见错误是在内部数据不同的部分使用不同的编码格式。最常见的是情况是一个应用以ISO-8859-1作为内部数据格式,结合libxml部分使用UTF-8格式。结果是一个应用程序要面对不同地内部数据格式。一部分代码执行后,它或其它部分代码将使用曲解的数据。

这个例子构造一个简单的文档,然后添加在命令行提供的内容到根元素并使用适当的编码将结果输出到

标准输出设备上。在这个例子中,我们使用ISO-8859-1编码。在命令输入的内容将被从ISO-8859-1转换到UTF-8。完整代码:附件H,编码转换例程代码。

包含在例子中的转换函数使用libxml的xmlFindCharEncodingHandler函数。

①xmlCharEncodingHandlerPtr handler;

②size = (int)strlen(in)+1;

out_size = size*2-1;

out = malloc((size_t)out_size);

③handler = xmlFindCharEncodingHandler(encoding);

④handler->input(out, &out_size, in, &temp);

⑤xmlSaveFormatFileEnc("-", doc, encoding, 1);

①定义一个xmlCharEncodingHandler函数指针。

②XmlCharEncodingHandler函数需要给出输入和输出字符串的大小,这里计算输入输出字符串。

③XmlFindCharEncodingHandler使用数据初始编码作为参数搜索libxml已经完成的转换器句柄并将

找到的函数指针返回,如果没有找到则返回NULL。

④The conversion function identified by handler requires as its arguments pointers to the input and output strings, along with the length of each. The lengths must be determined separately by the application.

由句柄指定的转换函数请求输入、输出字符中及它们的长度作为参数。这个长度必须由应用程序分别指定。

⑤用指定编码而不是UTF-8输出,我们使用xmlSaveFormatFileEnc指不定期编码方式。

A. 编译

Libxml包含一个脚本xml2-config,它一般用于编译和链接程序到库时产生标志。

为了取得预处理和编译标志,使用xml2-config –cflags,为了取得链接标志,使用xml2-config –libs。

其它有效的参数请使用xml2-config –help查阅。

B. 示例文档

John Fleck

June 2, 2002

example keyword

This is the headline

This is the body text.

C. Keyword例程代码

#include

#include

#include

#include

#include

void

parseStory (xmlDocPtr doc, xmlNodePtr cur) {

xmlChar *key;

cur = cur->xmlChildrenNode;

while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"keyword"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); printf("keyword: %s\n", key);

xmlFree(key);

}

cur = cur->next;

}

return;

}

static void

parseDoc(char *docname) {

xmlDocPtr doc;

xmlNodePtr cur;

doc = xmlParseFile(docname);

if (doc == NULL ) {

fprintf(stderr,"Document not parsed successfully. \n");

return;

}

cur = xmlDocGetRootElement(doc);

if (cur == NULL) {

fprintf(stderr,"empty document\n");

xmlFreeDoc(doc);

return;

}

if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {

fprintf(stderr,"document of the wrong type, root node != story"); xmlFreeDoc(doc);

return;

}

cur = cur->xmlChildrenNode;

while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){

parseStory (doc, cur);

}

cur = cur->next;

}

xmlFreeDoc(doc);

return;

}

int

main(int argc, char **argv) {

char *docname;

if (argc <= 1) {

printf("Usage: %s docname\n", argv[0]);

return(0);

}

docname = argv[1];

parseDoc (docnam e);

return (1);

}

libxml(三)

D. XPath例程代码

#include

#include

xmlDocPtr

getdoc (char *docname) {

xmlDocPtr doc;

doc = xmlParseFile(docname);

if (doc == NULL ) {

fprintf(stderr,"Document not parsed successfully. \n"); return NULL;

}

return doc;

}

xmlXPathObjectPtr

getnodeset (xmlDocPtr doc, xmlChar *xpath){ xmlXPathContextPtr context; xmlXPathObjectPtr result;

context = xmlXPathNewContext(doc);

result = xmlXPathEvalExpression(xpath, context); if(xmlXPathNodeSetIsEmpty(result->nodesetval)){ printf("No result\n");

return NULL;

}

xmlXPathFreeContext(context);

return result;

}

int

main(int argc, char **argv) {

char *docname;

xmlDocPtr doc;

xmlChar *xpath = ("//keyword"); xmlNodeSetPtr nodeset;

xmlXPathObjectPtr result;

int i;

xmlChar *keyword;

if (argc <= 1) {

printf("Usage: %s docname\n", argv[0]);

return(0);

}

docname = argv[1];

doc = getdoc(docname);

result = getnodeset (doc, xpath);

if (result) {

nodeset = result->nodesetval;

for (i=0; i < nodeset->nodeNr; i++) {

keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->printf ("keyword: %s\n", keyword);

xmlFree(keyword);

}

xmlXPathFreeObject (result);

}

xmlFreeDoc(doc);

xmlCleanupParser();

return (1);

}

E. 添加keyword例程代码

#include

#include

#include

#include

#include

void

parseStory (xmlDocPtr doc, xmlNodePtr cur, char *keyword) { xmlNewTextChild (cur, NULL, "keyword", keyword);

return;

}

xmlDocPtr

parseDoc(char *docname, char *keyword) {

xmlNodePtr cur;

doc = xmlParseFile(docname);

if (doc == NULL ) {

fprintf(stderr,"Document not parsed successfully. \n");

return (NULL);

}

cur = xmlDocGetRootElement(doc);

if (cur == NULL) {

fprintf(stderr,"empty document\n");

xmlFreeDoc(doc);

return (NULL);

}

if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {

fprintf(stderr,"document of the wrong type, root node != story"); xmlFreeDoc(doc);

return (NULL);

}

cur = cur->xmlChildrenNode;

while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){ parseStory (doc, cur, keyword);

}

cur = cur->next;

}

return(doc);

}

int

main(int argc, char **argv) {

char *keyword;

xmlDocPtr doc;

if (argc <= 2) {

printf("Usage: %s docname, keyword\n", argv[0]); return(0);

}

docname = argv[1];

keyword = argv[2];

doc = parseDoc (docname, keyword);

if (doc != NULL) {

xmlSaveFormatFile (docname, doc, 0); xmlFreeDoc(doc);

}

return (1);

}

F. 添加属性例程代码

#include

#include

#include

#include

#include

xmlDocPtr

parseDoc(char *docname, char *uri) {

xmlDocPtr doc;

xmlNodePtr cur;

xmlNodePtr newnode;

xmlAttrPtr newattr;

doc = xmlParseFile(docname);

if (doc == NULL ) {

fprintf(stderr,"Document not parsed successfully. \n");

return (NULL);

}

cur = xmlDocGetRootElement(doc);

if (cur == NULL) {

fprintf(stderr,"empty document\n");

xmlFreeDoc(doc);

return (NULL);

}

if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {

fprintf(stderr,"document of the wrong type, root node != story"); xmlFreeDoc(doc);

return (NULL);

}

newnode = xmlNewTextChild (cur, NULL, "reference", NULL); newattr = xmlNewProp (newnode, "uri", uri);

return(doc);

}

int

main(int argc, char **argv) {

char *docname;

char *uri;

xmlDocPtr doc;

if (argc <= 2) {

printf("Usage: %s docname, uri\n", argv[0]);

return(0);

}

docname = argv[1];

uri = argv[2];

doc = parseDoc (docname, uri);

if (doc != NULL) {

xmlSaveFormatFile (docname, doc, 1);

xmlFreeDoc(doc);

}

return (1);

}

G. 取得属性值例程代码

#include

#include

#include

#include

#include

void

getReference (xmlDocPtr doc, xmlNodePtr cur) {

xmlChar *uri;

cur = cur->xmlChildrenNode;

while (cur != NULL) {

if ((!xmlStrcmp(cur->name, (const xmlChar *)"reference"))) { uri = xmlGetProp(cur, "uri");

printf("uri: %s\n", uri);

xmlFree(uri);

}

cur = cur->next;

}

return;

}

void

parseDoc(char *docname) {

xmlDocPtr doc;

xmlNodePtr cur;

doc = xmlParseFile(docname);

if (doc == NULL ) {

fprintf(stderr,"Document not parsed successfully. \n");

return;

}

cur = xmlDocGetRootElement(doc);

if (cur == NULL) {

fprintf(stderr,"empty document\n");

xmlFreeDoc(doc);

return;

}

if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {

fprintf(stderr,"document of the wrong type, root node != story"); xmlFreeDoc(doc);

return;

}

getReference (doc, cur);

xmlFreeDoc(doc);

return;

}

int

main(int argc, char **argv) {

char *docname;

if (argc <= 1) {

printf("Usage: %s docname\n", argv[0]);

return(0);

}

docname = argv[1];

parseDoc (docnam e);

return (1);

}

H. 编码转换例程代码

#include

#include

unsigned char*

convert (unsigned char *in, char *encoding)

{

unsigned char *out;

int ret,size,out_size,temp; xmlCharEncodingHandlerPtr handler;

size = (int)strlen(in)+1;

out_size = size*2-1;

out = malloc((size_t)out_size);

if (out) {

handler = xmlFindCharEncodingHandler(encoding); if (!handler) {

free(out);

out = NULL;

}

}

if (out) {

temp=size-1;

ret = handler->input(out, &out_size, in, &temp); if (ret || temp-size+1) {

if (ret) {

java_Dom4j解析XML详解

学习:Dom4j 1、DOM4J简介 DOM4J是https://www.360docs.net/doc/dd1497856.html, 出品的一个开源XML 解析包。DOM4J应用于Java 平台,采用了Java 集合框架并完全支持DOM,SAX 和JAXP。 DOM4J 使用起来非常简单。只要你了解基本的XML-DOM 模型,就能使用。 Dom:把整个文档作为一个对象。 DOM4J 最大的特色是使用大量的接口。它的主要接口都在org.dom4j里面定义:

接口之间的继承关系如下: interface https://www.360docs.net/doc/dd1497856.html,ng.Cloneable interface org.dom4j.Node interface org.dom4j.Attribute interface org.dom4j.Branch interface org.dom4j.Document interface org.dom4j.Element interface org.dom4j.CharacterData interface org.dom4j.CDATA interface https://www.360docs.net/doc/dd1497856.html,ment interface org.dom4j.Text interface org.dom4j.DocumentType interface org.dom4j.Entity interface org.dom4j.ProcessingInstruction 2、XML文档操作1 2.1、读取XML文档: 读写XML文档主要依赖于org.dom4j.io包,有DOMReader和SAXReader两种方式。因为利用了相同的接口,它们的调用方式是一样的。 public static Docum ent load(String filenam e) { Document docum ent =null; try { SAXReader saxReader = new SAXReader(); docum ent =saxReader.read(new File(filename)); //读取XML文件,获得docum ent 对象 } catch (Exception ex) { ex.printStackTrace();

XML报文解析测试

XML报文解析测试 在平时工作中,难免会遇到把 XML 作为数据存储格式。面对目前种类繁多的解决方案,哪个最适合我们呢?在这篇文章中,我对这四种主流方案做一个不完全评测,仅仅针对遍历 XML 这块来测试,因为遍历 XML 是工作中使用最多的(至少我认为)。 预备 测试环境: AMD 毒龙1.4G OC 1.5G、256M DDR333、Windows2000 Server SP4、Sun JDK 1.4.1+Eclipse 2.1+Resin 2.1.8,在 Debug 模式下测试。 XML 文件格式如下: <?xml version="1.0" encoding="GB2312"?> <RESULT> <VALUE> <NO>A1234</NO> <ADDR>四川省XX县XX镇XX路X段XX号</ADDR> </VALUE> <VALUE> <NO>B1234</NO> <ADDR>四川省XX市XX乡XX村XX组</ADDR> </VALUE> </RESULT> 测试方法: 采用 JSP 端调用Bean(至于为什么采用JSP来调用,请参考: https://www.360docs.net/doc/dd1497856.html,/rosen/archive/2004/10/15/138324.aspx),让每一种方案分别解析10K、100K、1000K、10000K的 XML 文件,计算其消耗时间(单位:毫秒)。 JSP 文件: <%@ page contentType="text/html; charset=gb2312" %> <%@ page import="com.test.*"%> <html> <body> <% String args[]={""}; MyXMLReader.main(args); %>

Python解析XML的三种方式

一、什么是 XML? XML 被设计用来传输和存储数据。它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。 准备一个解析用的xml如下: 1 laoz 老曾 30 https://www.360docs.net/doc/dd1497856.html, 我是老曾 2 qz 强子 30 https://www.360docs.net/doc/dd1497856.html, 我是强子 1、第一行是 XML 声明 它定义 XML 的版本(1.0)和所使用的编码(utf-8 : 万国码, 可显示各种语言) 2、必须包含根元素(有且只有一个) 该元素是所有其他元素的父元素,这里的根元素是Data ..

所有的都被包含在里面 3、元素开始标签必须要有结束标签 < account > 元素有 6个子元素:、< description > 每个元素都有对应的关闭标签(跟HTML不一样,有一些是不需要关闭的,比如,
) 4、XML 标签对大小写敏感 比如是不一样的 5、XML 属性值必须加引号 < account name=laoz>这样会报错的,必须"laoz"才行 二、Python 对 XML 的解析 Python 有三种方法解析 XML,SAX,DOM,以及 ElementTree。 DOM会把整个XML读入内存,解析为树,因此占用内存大,解析慢,优点是可以任意遍历树的节点。SAX是流模式,边读边解析,占用内存小,解析快,缺点是我们需要自己处理事件。 1、利用DOM解析XML 一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

android 中对xml 进行解析

DOM解析器是通过将XML文档解析成树状模型并将其放入内存来完成解析工作的,而后对文档的操作都是在这个树状模型上完成的。这个在内存中的文档树将是文档实际大小的几倍。这样做的好处是结构清除、操作方便,而带来的麻烦就是极其耗费系统资源。而SAX正好克服了DOM的缺点,分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。 选择DOM 还是选择SAX,这取决于下面几个因素: 应用程序的目的:如果打算对数据作出更改并将它输出为XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用SAX 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。 数据容量:对于大型文件,SAX 是更好的选择。 数据将如何使用:如果只有数据中的少量部分会被使用,那么使用SAX 来将该部分数据提取到应用程序中可能更好。另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么SAX 也许不是恰当的选择。 对速度的需要:SAX 实现通常要比DOM 实现更快。 基于上面的分析,在基于Android系统的内存和CPU资源比较有限的手持设备上,只要我们不需要修改XML数据或者随机的访问XML数据,SAX尽管可能需要更多的编码工作,但是为了更小的内存和CPU 消耗,还是值得的。 另外,Android SDK中已经包含了JAXP对应的javax.xml.parsers包,和SAX对应org.xml.sax(当然DOM对应的org.w3c.dom包也包含在内),加上Android还提供了android.sax这样的包来方便SAX Handle的开发,基于JAXP和SAX这样的标准方法来开发不仅复杂度不高,即使出现问题在讨论组中寻求解决方案也是比较容易的。 android 中的xml解析应该是和java中一条道路主要分为sax 解析和的Dom 解析。 如下的介绍的相关的包和类均为android 环境下: sax解析对应为: org\xml\sax 包:xml解析 javax.xml.parsers.SAXParserFactory javax.xml.parsers.SAXParser 两个主要用于SAXParser的上下文建立

VC++ xml解析

三种最流行的开放源码XML 库是expat、libxml 和Xerces。 第一部分:DOM解析: 概述:DOM解析将会把一个完整的XML文档读进来,生成一个结构树。这样会要把XML文档全部都加载到内在中。所以解析起来的速度会要慢一些。 1、如何加载xml文件: //创建DOM,加载XML文档 MSXML::IXMLDOMDocumentPtr pCommandDoc; pCommandDoc.CreateInstance(__uuidof(MSXML::DOMDocument)); pCommandDoc->put_async(V ARIANT_FALSE); pCommandDoc->put_validateOnParse(VARIANT_FALSE); pCommandDoc->put_resolveExternals(V ARIANT_FALSE); pCommandDoc->put_preserveWhiteSpace(V ARIANT_TRUE); pCommandDoc->load(file.GetBuffer(0)); 2、在XML文档中查找指定的结点: //找到 MSXML::IXMLDOMNodePtr pRootNode=pCommandDoc->selectSingleNode("root/record"); if (pRootNode==NULL) { return ; } 3、得到XML文档中,结点的属性 CString strTemp; MSXML::IXMLDOMNamedNodeMapPtr pAttrs = NULL; pRootNode->get_attributes(&pAttrs); if (pAttrs==NULL) { return; } MSXML::IXMLDOMNodePtr pRequestTypeAttr=pAttrs->getQualifiedItem("name",""); _bstr_t strRequestType=pRequestTypeAttr->Gettext(); strTemp=strRequestType.operator char *(); 4、得到结点的内容 _bstr_t strVisiPort=pNode->Gettext(); 5、设置结点的内容 HRESULT hr=pNode->put_text(_bstr_t(m_strGatewayPassword)); 6、设置一个属性内容 IXMLDOMAttribute *pa=NULL; bstr = SysAllocString(L"属性1"); pXMLDom->createAttribute(bstr,&pNode); var = VariantString(L"strin"); pa->put_value(var); pRoot->setAttributeNode(pa, &pa1); 第二部分、如何使用SAX解析

XML创建与解析常用方法介绍

XML解析方式介绍 1.DOM4J(Document Object Model for Java) 虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。 为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。 在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java 开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。 DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J. 【优点】 ①大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。 ②支持XPath。 ③有很好的性能。 【缺点】 ①大量使用了接口,API较为复杂。 2.SAX(Simple API for XML) SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX 采用的是事件模型。

四种XML解析器比较

1.详解 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 2)SAX SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。 而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。 选择DOM还是选择SAX?对于需要自己编写代码来处理XML文档的开发人员来说,选择DOM 还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档,而SAX采用的事件模型。 DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档,所以对性能和内存的要求比较高,尤其是遇到很大的XML文件的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频繁的改变的服务中。 SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。 3)JDOM https://www.360docs.net/doc/dd1497856.html, JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102” 将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。 JDOM与DOM主要有两方面不同。首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。 JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开

四中最常用的XML文件解析总结

XML文件学习总结 掌握了XML文件解析的常用的4中方式:DOM解析、SAX 解析、STAX解析以及DOM4j解析XML文件。 一、DOM 解析xml文件 public List parse(String url) throws Exception{ // 1、创建解析工厂 D ocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//创建工厂是单例模式,不能直接new对象,需要调用newInstance来创建对象。 // 2、创建解析器 D ocumentBuilder builder = factory.newDocumentBuilder(); // 3、创建解析器的url F ile file = new File(url); // 4、得到解析后的Document对象 D ocument doncument = builder.parse(file); // 5、通过得到节点名字得到所有同名节点的集合NodeList N odeList nodeList = doncument.getElementsByTagName("student"); // 6、遍历NodeList集合 f or (int i = 0; i < nodeList.getLength(); i++) { // 得到每个节点对象 Node studentNode = nodeList.item(i); Student st = new Student(); NamedNodeMap map = studentNode.getAttributes(); //for(int j=0;j

Android SAX 方式解析XML 字符串

这个是主类: import java.io.StringReader; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; public class ParsingXML extends Activity { private final String MY_DEBUG_TAG = "WeatherForcaster"; public void onCreate(Bundle icicle) { super.onCreate(icicle); TextView tv = new TextView(this); String xml = "aHR0cDovLzE5Mi4xNjguMTA0LjExMy9ldW1zL2NsaWV udC90ZW1 wbGF0ZTIwMDA vbW9iaWxlZW50cnkucGhwP3VzZXJuYW1lPWNlc2hp"; // 创建一个新的字符串 StringReader read = new StringReader(xml); // 创建新的输入源SAX 解析器将使用InputSource 对象来确定如何读取XML 输入 InputSource source = new InputSource(read); try { SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); ExampleHandler myExampleHandler = new ExampleHandler(); xr.setContentHandler(myExampleHandler); xr.parse(source); ParsedExampleDataSet parsedExampleDataSet = myExampleHandler .getParsedData(); String url=Base64Coder.decodeString(parsedExampleDataSet.toString()); tv.setText(url); } catch (Exception e) { tv.setText("Error: " + e.getMessage()); Log.e(MY_DEBUG_TAG, "WeatherQueryError", e); } this.setContentView(tv); } } 下面两个类是以SPX 方式解析XML字符串

使用DOM4j解析xml文件

Xml文件: studentname 78 78 98 studentname 77 68 88 JAVA文件: import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** *DOM4j对xml文件的操作 *操作DOM4j的时候注意要导入3个jar包,否则会报异常 *dom4j-1.6.1.jar *jaxen-1.1-beta-6.jar *saxpath.jar **/ public class ReaderDom4j {

xml文件解析

查找结点,读取结点属性------------------------------------------------------ 获取结点的属性------------------------------------- 设置结点的属性------------------------------------------------ 给结点添加新属性------------------------------------------- 设置一个结点的内容---------------------------------------------------- 添加新节点---------------------------------------------------- 编码问题------------------------------------------------------------------ XML树: John Fleck June 2, 2002 example keyword This is the headline This is the body text. 1:查找结点 #include #include #include #include #include Void parseStory (xmlDocPtr doc, xmlNodePtr cur) { xmlChar *key; cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"keyword")))

Java解析XML文件

Java解析XML文件 ========================================== xml文件 <?xml version="1.0" encoding="GB2312"?> <RESULT> <VALUE> <NO>A1234</NO> <ADDR>四川省XX县XX镇XX路X段XX号</ADDR> </VALUE> <VALUE> <NO>B1234</NO> <ADDR>四川省XX市XX乡XX村XX组</ADDR> </VALUE> </RESULT> ========================================== 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航,而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 import java.io.*; import java.util.*; import org.w3c.dom.*; import javax.xml.parsers.*; public class MyXMLReader{ public static void main(String arge[]){ long lasting =System.currentTimeMillis(); try{ File f=new File("data_10k.xml"); DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document doc = builder.parse(f); NodeList nl = doc.getElementsByT agName("VALUE"); for (int i=0;i<nl.getLength();i++){ System.out.print("车牌号码:" +

java读写xml文件的方法

在java环境下读取xml文件的方法主要有4种:DOM、SAX、JDOM、JAXB 1. DOM(Document Object Model) 此方法主要由W3C提供,它将xml文件全部读入内存中,然后将各个元素组成一棵数据树,以便快速的访问各个节点。因此非常消耗系统性能,对比较大的文档不适宜采用DOM方法来解析。 DOM API 直接沿袭了 XML 规范。每个结点都可以扩展的基于 Node 的接口,就多态性的观点来讲,它是优秀的,但是在Java 语言中的应用不方便,并且可读性不强。 实例: Java代码 1.import javax.xml.parsers.*; 2.//XML解析器接口 3.import org.w3c.dom.*; 4.//XML的DOM实现 5.import org.apache.crimson.tree.XmlDocument; 6.//写XML文件要用到 7.DocumentBuilderFactory factory = DocumentBuilderFactory.newInst ance(); 8. //允许名字空间 9. factory.setNamespaceAware(true); 10. //允许验证 11. factory.setValidating(true); 12. //获得DocumentBuilder的一个实例 13.try { 14. DocumentBuilder builder = factory.newDocumentBuilder(); 15.} catch (ParserConfigurationException pce) { 16.System.err.println(pce); 17.// 出异常时输出异常信息,然后退出,下同 18.System.exit(1); 19.} 20.//解析文档,并获得一个Document实例。 21.try { 22.Document doc = builder.parse(fileURI); 23.} catch (DOMException dom) { 24.System.err.println(dom.getMessage()); 25.System.exit(1); 26.} catch (IOException ioe) { 27.System.err.println(ioe); 28.System.exit(1); 29.}

xml的四种解析方法及源代码

xml的四种解析方法及源代码(SAX、DOM、JDOM、DOM4J) 第一种:SAX解析 SAX处理机制:SAX是一种基于事件驱动的API。利用SAX解析XML文档,牵涉到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发生事件,如元素开始和元素结束事件;而事件处理器则负责对事件做出响应,对传递的XML数据进行处理。 测试用的xml文件:db.xml Xml代码 oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@localhost:1521:oracle scott tiger DTD文件db.dtd Xml代码

SAX解析实例一 org.xml.sax.DefalutHandler类: 可以扩展该类,给出自己的解析实现SAXPrinter.java Java代码 import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXPrinter extends DefaultHandler { /** *//** * 文档开始事件 */ public void startDocument() throws SAXException { System.out.println("");

jdom读取解析XML文件

jdom学习读取XML文件 用JDOM读取XML文件需先用org.jdom.input.SAXBuilder对象的build()方法创建Document对象,然后用Document类、Element类等的方法读取所需的内容。 例如: 8G 200 1580 10G 500 3000 则解析类: import java.util.*; import org.jdom.*; import org.jdom.input.SAXBuilder; publicclass Sample { publicstaticvoid main(String[] args) throws Exception{ SAXBuildersb=new SAXBuilder(); Document doc=sb.build(Sample.class.getClassLoader().getResourceAsStream("test. xml")); //构造文档对象 Element root=doc.getRootElement(); //获取根元素 List list=root.getChildren("disk");//取名字为disk的所有元素 for(int i=0;i

XML文档对象模型解析

XML文档对象模型 1)DOMDocument对象:该对象描述全部的文档映射表,文档映射表包含了XML 文档里的所有信息。 常用方法 常用属性 2)IXMLDOMNode对象:该对象描述XML文档里的节点。这个节点可以是元素、属性、处理指令、文本或者其他存储在XML文档里的信息。 常用方法 常用属性 3)IXMLDOMNodeList对象:该对象描述IXMLDOMNode对象的集合,并可使用该对象遍历这个集合。IXMLDOMNodeList对象里的节点集合可以用数值该问。 常用方法 常用属性 4)IXMLDOMParseError对象:该对象用来验证XML文档对于Schema或DTD的正确性,并且取得在验证过程中产生的错误信息。 常用方法 常用属性 * DOMDocument对象常用方法: a)createElement(elementName) ---- 该方法以元素名为参数创建一个用此参数命名的元素节点。(不能创建名称空间受限制的元素。如果要创建名称空间受限制的元素,必须使用createNode()方法) 例: doc.createElement("PRODUCT"),有些用到:doc-> creatElement('item') b)createAttribute(attributeName) ---- 该方法以属性名为参数创建一个用此参数命名的属性节点。 例: doc.createAttribute("PRODID") xml中表现形式:下载通道名称 c)createComment(text) ---- 该方法以字符串为参数创建一个包含此字符串的注释节点。

xml文件解析doc.doc

课堂笔记 一、数据库中对数据的操作 1、distinct:用来消除多列连和之后的重复行 2、Where: ※between A and B:范围在之间的值 如:查询英语分数在80-90分之间的 select name,english from student where english>=80 and english<=90; ※in(列表):在列表之中 如:查询语文分数为81,82,83的学生 select name,english from student where english in(80,90,82); ※like(表达式):模糊查询, %代表多个字符, _代表单个字符 如:查询所有姓张的学生的成绩 select name,english,math,chinese from student where name like '张%'; %代表不定字符,以张开头,'_'代表一个字符 3、order by: 语法 select 列名from 表名order by 列名asc|desc 注意事项 order by 指定排序的列名可以是表中的列名, 也可以是SELECT语句后面起的别名ASC为升序, DESC为降序默认为升序 order by应在查询语句的结尾 如: 查询学生成绩, 按照语文从高到低排序, 如果语文相同, 按照英语从高到低排序 select * from student order by chinese desc,english desc; 4、聚合函数 ①COUNT函数 语法 select COUNT(*)|COUNT(列名) from 表名[WHERE 条件语句]

java解析XMl文件完整版DOM解析XML

package XML; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DomTest { private Document doc;

//获得DOM树,元素的添加删除都会用到DOM树所以抽出一个方法来 public void document(){ try { // 1.创建解析工厂对象 DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); // 2.通过解析器工厂对象创建解析器对象 DocumentBuilder document = factory.newDocumentBuilder(); // 3.指定解析XML文件,parse("路径")里面写的是文件的路径,并不是文件名。我这里是在这个项目里面,所有写的是相对路径。 doc = document.parse("NewFile.xml"); } catch (Exception e) { } } //解析XML文件

相关文档
最新文档