POCO::XML(二) 简单读XML文档

来源:互联网 发布:微信报码编码软件 编辑:程序博客网 时间:2024/06/05 18:54

先来看一下在Poco中XML各元素被抽象成什么关系:


可以看到,任何元素都被抽象成Node,同时又分为三种类型的节点。(Attr和Notation看成一种)

第一种类型:CharacterData,这类Node是Name不可变,而Value可以由用户自定义。

第二种类型:AbstractContainerNode,这类Node有个特点,即含有属性,特别的对于Element节点,Name可以由用户自定义,而Value不可变。

第三种类型:右边两个,它们既可以改变Name,也可以改变Value。

下面是sample.xml文本:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--This is a comment.--><zhong><guo long="5">hahah</guo></zhong>
对于上面这一份XML数据,有下面一份代码执行操作:

InputSource src("./sample.xml");//设置源数据try{DOMParser parser;//创建一个分析者AutoPtr<Document> pDoc = parser.parse(&src);//开始分析,并返回指向分析后数据的指针,用AutoPtr是为了自动回收垃圾NodeIterator it(pDoc, NodeFilter::SHOW_ALL);//创建一个节点迭代器,默认迭代显示全部nodeNode* pNode = it.nextNode();//此时指向第一个while (pNode){NamedNodeMap* map = pNode->attributes();//试图返回这个节点的属性if(map)//看看是否真有属性{for(int i = 0 ; i < map->length() ; i++)//属性肯定至少0个,用循环一个个取出{Node* attr = map->item(i);std::cout << attr->nodeName() << std::endl;std::cout << attr->nodeValue() << std::endl;}//属性结束}std::cout << pNode->nodeName() << std::endl;//取出当前节点的Namestd::cout<< pNode->nodeValue() << std::endl;//取出当前节点的ValuepNode = it.nextNode();//指向下一个node}}catch (Exception& exc){std::cerr << exc.displayText() << std::endl;}
可以看出,节点的Name和Value同节点属性的Name和Value取得方法是同样的,都是用nodeName()和nodeValue()。

看一下显示结果:


在把数据拿过来看看:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><!--This is a comment.--><zhong><guo long="5">hahah</guo></zhong>
可以看出,程序虽是我们写的,可是具体的遍历行为却是Poco自己定义的。首先明确,有#的全都是系统的const string,也就体现了Name不可变。

Poco先发现Document类型,把它的Name打印出:#Document,再打印出它的Value,由于在源码中,其值为空字符串,所以什么也没有。

Poco再发现Comment类型,把它的Name打印出:#Comment,由于Comment的值是可以由用户自定义的,所以存在并显示出“This is a comment”。

Poco再发现Element类型,把它的Name打印出:zhong,由于element的Name是由用户定义的,所以存在,然而,它没有值,只可能有属性。

Poco再发现Text类型,把它的Name打印出:#Text,这个text是element zhong 的,它不可以指定Name,但可以指定Value,这里没有Value,所以没有什么出现。

Poco再发现Attr类型,这说明判断属性的循环进去了,把它的Name打印出:long ,再打印Value 5。由于程序语句执行顺序,这个属性是element guo的

Poco再发现Element类型,把它的Name打印出:guo,没有Value可以打印出。

Poco再发现Text类型,把它的Name打印出:#Text,这个text是element guo的,它不可以指定Name,但可以指定Value,这里Value是“hahah”。

最后,值得注意一下,我发现父子Element元素之间还有一个Text element,比如上面这份数据,在</guo> 和 </zhong>之间就存在这样一个元素,所以在屏幕上最后会打印Name:#Text,而没有值。

可以这样设置:

<zhong>wo<guo>shi<ren>zhong</ren>guo</guo>ren</zhong>
这样,解析后的每个Text元素都有Value了。

还没有涉及更加复杂的XML操作,因为我在项目中对XML数据格式的要求不太复杂,主要集中在节点属性这一块,就这足够了。

以上分析建立在本人没有系统的学习过XML知识的前提下。

谢谢观赏!





原创粉丝点击