如何用libxml2html select 默认选中解析器解析HTML文件

如何用libxml2 默认解析器解析HTML文件
[问题点数:20分,结帖人qhlonline]
如何用libxml2 默认解析器解析HTML文件
[问题点数:20分,结帖人qhlonline]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年9月 Linux/Unix社区大版内专家分月排行榜第二2012年7月 Linux/Unix社区大版内专家分月排行榜第二
2012年6月 Linux/Unix社区大版内专家分月排行榜第三2009年4月 硬件/嵌入开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。XML DOM 解析器错误(Parser Errors)
XML DOM 解析器错误(Parser Errors)
微软的 parseError 对象可用于从微软的 XML 解析器中取回错误信息。
parseError 对象
在您试图打开一个 XML 文档时,就可能发生一个解析器错误(parser-error)。
通过这个 parseError 对象,您可取回错误代码、引起错误的行等等。
注释:parseError对象不属于 W3C DOM 标准!
文件错误(File Error)
在下面的代码中,我们会试图加载一个不存在的文件,并显示某些错误属性:
var xmlDoc = new ActiveXObject(&Microsoft.XMLDOM&)
xmlDoc.async=&false&
xmlDoc.load(&ksdjf.xml&)
document.write(&Error code: & + xmlDoc.parseError.errorCode)
document.write(&&br /&Error reason: & + xmlDoc.parseError.reason)
document.write(&&br /&Error line: & + xmlDoc.parseError.line)
XML 错误(XML Error)
在下面的代码中,我们会让解析器加载一个形式不良的 XML 文档。
(您可以在我们的
中阅读更多有关形式良好且有效的 XML。)
var xmlDoc = new ActiveXObject(&Microsoft.XMLDOM&)
xmlDoc.async=&false&
xmlDoc.load(&note_error.xml&)
document.write(&Error code: & + xmlDoc.parseError.errorCode)
document.write(&&br /&Error reason: & + xmlDoc.parseError.reason)
document.write(&&br /&Error line: & + xmlDoc.parseError.line)
parseError 对象的属性
返回一个长整型错误码。
返回包含错误原因的字符串。
返回表示错误行号的长整型。
返回表示错误的行位置的长整型。
返回包含引起错误的行的字符串。
返回指向被加载文档的 URL。
返回错误的一个长整型文件位置。<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
学习如何在您的 UNIX&#174; 应用程序中使用 XML(可扩展标记语言)。本文面向那些不熟悉 XML 的 UNIX 开发人员,研究了 Gnome 项目中开发的 XML 库。在从总体上对 XML 进行简单的解释之后,您将看到 UNIX 应用程序开发人员可能用来解析和管理 XML 格式的配置文件的示例代码,其中使用了 LibXML2 库。
(), 自由撰稿人
David Dougall 于 2001 年毕业于杨百翰大学 (Brigham Young University) 并获得计算机工程硕士学位。他在该大学的工程技术学院从事了六年的 UNIX 系统管理员工作。您可以通过
与 David 联系。
() Backstop Media
Nicholas Chase 曾参与多家公司的网站开发工作,如 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers。Nick 曾经是一位高中物理教师、低级放射性废物设备的管理员、在线科幻小说杂志的编辑、多媒体工程师、Oracle 讲师和一家交互式通信公司的首席技术官。他已经出版了多本图书,其中包括 XML Primer Plus (Sams)。您可以通过
与 Nick 联系。
引言要创建完善的、高度互操作性的应用程序,XML 是一个很好的选择,因为它正越来越广泛地应用于数据存储和配置文件管理。本文研究了一个使用 XML(可扩展标记语言)作为其配置文件格式的示例应用程序,并通过该示例向您介绍如何在自己的 UNIX 应用程序中使用 XML。该示例应用程序使用 Perl 编写,并且其中使用了基于 Gnome 项目的 LibXML2 库的 Perl 模块。在给出 XML 的简单定义之后,本文介绍了一个使用 XML 编写的示例配置文件。然后,通过示例代码来介绍如何解析这个配置文件。系统管理员可以手动修改该配置文件,但通常在一定程度上,需要应用程序直接地修改该配置文件。然后,本文通过一个示例介绍如何以编程的方式向这个 XML 文档添加新的配置选项,以及如何修改当前条目的值。最后,本文介绍了将这个经过修改的配置文件写入到磁盘的代码。关于 XML在开始研究 LibXML2 库之前,让我们先来巩固一下 XML 的相关基础。XML 是一种基于文本的格式,它可用来创建能够通过各种语言和平台访问的结构化数据。它包括一系列类似 HTML 的标记,并以树型结构来对这些标记进行排列。例如,可参见 中介绍的简单文档。这是部分中研究的配置文件示例的简化版本。为了更清楚地显示 XML 的一般概念,所以对其进行了简化。清单 1. 一个简单的 XML 文件&?xml version="1.0" encoding="UTF-8"?&
&owner&root&/owner&
&action&delete&/action&
&age units="days"&10&/age&
&/files& 中的第一行是 XML 声明,它告诉负责处理 XML 的应用程序,即解析器,将要处理的 XML 的版本。大部分的文件使用版本 1.0 编写,但也有少量的版本 1.1 的文件。它还定义了所使用的编码。大部分文件使用 UTF-8,但是,XML 设计用来集成各种语言中的数据,包括那些不使用英语字母的语言。接下来出现的是元素。一个元素以开始标记 开始(如 &files&),并以结束标记 结束(如 &/files&),其中使用斜线 (/) 来区别于开始标记。元素是 Node 的一种类型。XML 文档对象模型 (DOM) 定义了几种不同的 Nodes 类型,包括 Elements(如 files 或者 age)、Attributes(如 units)和 Text(如 root 或者 10)。元素可以具有子节点。例如,age 元素有一个子元素,即文本节点 10。而 files 元素有七个子元素。其中三个很明显。它们分别是三个子元素:owner、action 和 age。其他四个分别是元素前后的空白文本符号。XML 解析器可以利用这种父子结构来遍历文档,甚至修改文档的结构或内容。LibXML2 是这样的解析器中的其中一种,并且文中的示例应用程序正是使用这种结构来实现该目的。对于各种不同的环境,有许多不同的解析器和库。LibXML2 是用于 UNIX 环境的解析器和库中最好的一种,并且经过扩展,它提供了对几种脚本语言的支持,如 Perl 和 Python。作为研究工作的第一步,让我们先来看一个示例配置文件。配置文件文中的示例应用程序读取了特定文件的操作列表。而配置文件定义了这些文件和操作。假设该配置文件是位于 UNIX 文件系统中某个位置的一个文件。例如,在 UNIX 系统 cron 中可能会使用这个配置文件。该 XML 文件定义了目录路径和根据条件要执行的操作,而这些条件则包括所有者和文件存在时间(请参见)。清单 2. 配置文件&?xml version="1.0" encoding="UTF-8"?&
&filesystem&
&dirname&/var&/dirname&
&owner&root&/owner&
&action&delete&/action&
&age units="days"&10&/age&
&owner&any&/owner&
&action&delete&/action&
&age units="hours"&96&/age&
&dirname&/tmp&/dirname&
&owner&any&/owner&
&action&delete&/action&
&age units="hours"&24&/age&
&/filesystem&在本例中,根 元素是 filesystem,它包含两个 path 元素。每个 path 元素包含相应的目录名和一个或多个 files 元素。每个 files 元素通过 age 元素的 units 属性中指定的存在时间单位,定义了当用户或用户文件达到特定的存在时间时,应用程序应采取的操作。请记住,空白符号是有意义的。从结构的观点来看,每个空白符号组成了独立的 Text 节点。在产品环境中,一个编写完善的 UNIX 应用程序不仅应该具有读取数据并对其进行操作的能力,而且还应具有根据用户输入对数据进行添加、删除和修改的能力。现在让我们来研究使用该数据的应用程序。示例程序本文余下的内容通过示例代码介绍对 XML 配置文件的解析和管理。这些示例逐一地读取并修改配置文件,但在 UNIX 开发人员的日常工作中,您可以在任何类型的任务中使用这些概念。而且,因为使用了 LibXML2 库,所以您可以将这些概念插入到几乎任何的 UNIX 应用程序中。我们将在本文中介绍使用 Perl 版本的 LibXML2 库的示例。Internet 上的大部分文档都在讨论如何使用 Java&#8482; 或 Microsoft&#174; Visual Studio 工具进行编程,但对于 UNIX 用户或开发人员来说,Perl 则更有价值。 显示了解析该 XML 文档所需的 Perl 模块。清单 3. 需要的库XML::LibXML
XML::LibXML::Common
XML::NamespaceSupport
XML::SAX下面部分中介绍的代码仅仅只是一个框架。可分三个部分对其进行介绍:解析、操作和导出。在加载和解析阶段中,可能会将数据加载到 Perl 变量中,如列表或哈希,但由于每个程序员都有他/她自己首选的方法来完成这项任务,所以我们把它留给读者作为一项练习。下面的代码只是简单地显示了数据,以此说明该脚本正确地找到了相应的数据。在操作阶段中,该程序对 XML 文档中的元素进行添加、修改和删除的数据更新操作。通常地,这将按照用户的操作来进行。最后在导出阶段中,将经过修改的最终的文档写回到磁盘。加载和解析数据对于应用程序来说,读取 XML 文件的第一步是加载该数据并将其解析为一个 Document 对象。在此基础上,可以对 DOM 树进行遍历以获取特定的节点。让我们来看看 中的代码是如何完成该任务的。清单 4. 加载和解析 example.xml 的代码my $parser = XML::LibXML-&new();
my $doc = $parser-&parse_file("example.xml");
$filesystem = $doc-&getDocumentElement();
@nodes=$filesystem-&childN
foreach $node (@nodes) {
if($node-&nodeType==ELEMENT_NODE) { # ignore text nodes
# just get the first match
@dirnames = $node-&getElementsByTagName("dirname")-&item(0);
foreach $dirname (@dirnames) {
print "dirname: " . $dirname-&textContent . "\n";
# push this into an array
# get all children
@files = $node-&getChildrenByTagName("files");
foreach $file (@files) {
foreach $values ($file-&childNodes) {
# ignore text nodes
if($values-&nodeType!=XML_TEXT_NODE) {
if($values-&nodeName() eq "age") {
# check for attribute, otherwise, use default of 'hours'
if($values-&hasAttributes()) {
print $values-&nodeName() . ": " .
$values-&textC
print " " . $values-&attributes-&item(0)-&value();
print "\n";
print $values-&nodeName() . ": " .
$values-&textC
print " hours\n";
# calculate extended value from units and put in a
# hash linked with this dirname, etc.
print $values-&nodeName() . ": " .
$values-&textC
print "\n";
# put this value into a hash linked with $dirname.
# We may have multiple entries for each $dirname, so
# perhaps use an array within a hash
}首先,在 中,创建了解析器并将 XML 从文件加载到 XML::LibXML::Document 变量。这个对象包含了整个 XML 树,并且具有与之关联的各种方法可用来搜索节点、导出、验证和创建新的节点。本文将在后面的几个部分中对其中的一些方法进行介绍。从代码的起始处开始,您可以看到 getDocumentElement() 方法,它用于返回文档的根节点。从这个根节点,就可以遍历整个 XML 树。主 foreach 循环对父 filesystem 元素中的每个节点进行循环。当仅选择元素节点时,该循环将得到 path 元素。getElementsByTagName() 方法根据相应的名称在节点中搜索对应的元素,并通过 NodeList 对象返回它们。每个 path 元素包含了一个 dirname 元素,所以代码搜索名称为 dirname 的元素,并获取其中的第一个条目。在代码中只能选择 ELEMENT 类型的节点,因为该方法不支持 TEXT 节点,并且会在 Perl 中产生一个不可恢复的错误。在一个 path 元素中可能存在多个 files 元素,所以代码对 getChildrenByTagName() 方法的每一个元素进行循环,这个方法类似于 getElementsByTagName(),但仅搜索目标节点的直接子节点。这将返回所有的 files 元素,但必须进行进一步的解析以获得 owner、action 和 age 元素。在得到了这些节点之后,可以调用 textContent 以从相应的元素中获取实际的值。下面显示的是选择 ELEMENT 节点孩子的 TEXT 节点值的快捷方法:print $values-&nodeName() . ": "
print $values-&firstChild()-&nodeValue();在使用 age 元素的情况下,还可以通过一个属性来指定时间单位。使用 hasAttributes() 和 Attributes 函数,该程序可以提取相应的属性,如果它存在话。如果它不存在,那么该程序使用缺省值 hours。现在让我们来介绍对数据的操作,这样就能够以编程的方式来添加、删除和编辑操作。对数据进行操作现有的代码本身就是一个有用的程序。用户可以很容易地以手动地方式对该 XML 文件完成程序所做的修改。然而,有经验的 UNIX 开发人员还可以使用 XML 函数在程序中直接对文件进行修改。例如,可以包含用于添加新的操作或删除现有操作的菜单选项。要实现这个目的,让我们来看看在程序中对数据进行操作的代码。清单 5. 向文档添加填充的 path 节点$newnode = $doc-&createElement("path");
$newdirnode = $doc-&createElement("dirname");
$newdirnode-&appendText("/root");
$newfilesnode = $doc-&createElement("files");
$newownernode = $doc-&createElement("owner");
$newownernode-&appendText("any");
$newactionnode = $doc-&createElement("action");
$newactionnode-&appendText("archive");
$newagenode = $doc-&createElement("age");
$newagenode-&appendText("30");
$newagenode-&setAttribute("units","days");
$newfilesnode-&addChild($newownernode);
$newfilesnode-&addChild($newactionnode);
$newfilesnode-&addChild($newagenode);
$newnode-&addChild($newdirnode);
$newnode-&addChild($newfilesnode);
$filesystem-&addChild($newnode); 中的代码创建了一个 path 元素,并为其填充了所有的元素。然后,将这个新创建的节点添加到根元素,即 filesystem。需要使用 XML::LibXML::Document 类的 createElement() 方法来创建每个元素。(正是 Document 创建了您所需要的任何新的节点。)该方法返回一个尚未连接到文档树中任何位置的空节点。然后可以使用 XML::LibXML::Element
类的 appendText() 方法为每个节点添加内容。此外,相对于创建一个新的 TEXT 节点,然后对其进行填充并将其添加到相应的元素,这是一种快捷的方法。可以使用 setAttribute() 方法来添加属性,如果在目标元素中不存在给定名称的属性,该方法将自动创建一个新的 ATTRIBUTE 节点。在完成每个节点的创建并分别对它们进行了填充之后,可以使用要求的子节点作为参数,对父节点调用 addChild() 方法。因此在上面的代码中,$newownernode 成为了 $newfilesnode 的子节点。文档中所有的节点保持其添加时的顺序。如果您希望指定其他的顺序,可以使用 insertAfter() 或 insertBefore() 函数。将每个节点添加到相应的父节点,直到最后将主父节点添加到已经存在于文档中的一个节点。在上面的示例中,将该节点添加到了 filesystem 根节点。(如果您是从头开始创建该文档,那么可以对 Document 对象本身调用 addChild() 来添加根元素,然后再向该元素添加任何其他的节点。)正如前面所解释的, 中的示例 XML 代码是一种可读的格式。换行和缩进使得文档更容易阅读。XML 解析器将读取所有这些字符,并将其作为一个 TEXT 类型的节点。 中的示例没有添加任何这样的 TEXT 节点。因此,该示例的输出将不包含任何换行或缩进。如果您希望创建这种空白字符,那么需要使用 XML::LibXML::Text 类来创建 TEXT 类型的节点,或者使用该文档对象的 createTextNode() 函数。该构造函数的返回值是一个节点,可以使用与上面示例中相同的方式将其添加到树中。要更改文件的内容,可以直接设置相关 TEXT 节点的 nodeValue(),或者替换整个元素:$newnode = $doc-&createElement("owner");
$newnode-&appendText("toor");
$oldnode-&replaceNode($newnode);要删除一个节点,有以下几种选择。一种方法是仅将其从结构中删除,代码如下所示:$file-&unbindNode();在找到需要删除的节点之后,通过一行命令即可将其从结构中删除,但并没有从文档中删除。这个函数调用直到程序结束时才真正销毁该数据结构。如果您需要将节点移动到树中的其他部分,那么可以使用相同的变量来调用 addNode() 以将其重新添加到文档中新的位置。您还可以使用 removeChild() 或 removeChildNodes() 函数,这样可以从文档中彻底地释放相应的资源。保存 XML 文件在一些编程语言中,将 XML 文档保存到文件中可能比较烦琐,但幸运的是,LibXML 让这项任务变得非常简单:$doc-&toFile("example.xml");在对数据进行的所有的操作中,这是最简单的一种操作。在对内存中的 XML 文档完成了相应的修改之后,只需使用一个函数调用就可以将其写回到对应的配置文件中。还可以使用相关的 Perl 函数,如 toString() 和 toFH(),这些函数分别将 XML 输出到一个字符串变量或者一个已打开的 Perl 文件句柄,而文件句柄将为您的应用程序的构建带来更大的灵活性。结束语通过提供 LibXML2 库以及对 Perl 模块的支持,Gnome 项目完成了一项很有价值的任务。本文对管理和使用 XML 配置文件所需要的三个重要的步骤进行了介绍。解析阶段可能是最复杂的,因为它需要一定程度的递归设计来解析 XML 树。尽管有些烦琐,但对内存中 XML 文档的操作却是非常简单明了的。使用 LibXML2 库导出经过修改的配置,也是非常容易的。尽管相对于标准的UNIX 思维方式来说,需要进行一定的思维模式转移,但是 XML 可以为数据管理提供一种功能强大的方法。与简单的数据库格式相比,树型结构提供了更加灵活的数据视图。在开发新的应用程序或修改旧的应用程序时,可将其规范化为使用 XML 配置文件,在进行规范化的过程中可以很容易地使用 Gnome 项目所提供的免费的标准库,正如本文所介绍的。
参考资料 您可以参阅本文在 developerWorks 全球站点上的 :有关 XML C 解析器和 Gnome 工具包的更详细的信息,请访问 LibXML 站点。:该教程介绍了如何在您的应用程序中开始使用 XML。(developerWorks,2003 年 7 月):该教程介绍了关于 DOM(文档对象模型)的文档结构。DOM 允许开发人员引用、检索和更改 XML 结构中的项目,对于使用 XML 来说,它是必不可少的。请访问 developerWorks 的 。:其中给出了面向不同编程语言的完整的 XML 解析器列表。:想了解更多内容吗?developerWorks 的 AIX and UNIX 专区提供数百篇关于 AIX 和 UNIX 的文章以及入门级、中级和高级教程,将让您大开眼界。了解关于 的最新消息。:有关 Perl 模块和文档仓库的更详细的信息,请访问这个站点。:获取 Perl 语言的完整的 XML 工具包。使用 开发您的下一个项目,可直接从 developerWorks 下载这些试用软件。参与 ,从而参加到 developerWorks 社区中来。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=AIX and UNIX, XMLArticleID=129300ArticleTitle=使用 LibXML2 处理配置文件publish-date=dxwangtcg 的BLOG
用户名:dxwangtcg
文章数:367
评论数:187
访问量:977567
注册日期:
阅读量:24883
阅读量:272737
阅读量:1004780
阅读量:152641
51CTO推荐博文
TinyXml是一个基于DOM模型的、非验证的轻量级C++解释器。
1.&&&&& SAX和DOM
目前XML的解析主要有两大模型:SAX和DOM。
其中SAX是基于事件的,其基本工作流程是分析XML文档,当发现了一个新的元素时,产生一个对应事件,并调用相应的用户处理函数。这种方式占用内存少,速度快,但用户程序相应得会比较复杂。
而DOM(文档对象模型),则是在分析时,一次性的将整个XML文档进行分析,并在内存中形成对应的树结构,同时,向用户提供一系列的接口来访问和编辑该树结构。这种方式占用内存大,速度往往慢于SAX,但可以给用户提供一个面向对象的访问接口,对用户更为友好。
2.&&&&& 验证和非验证
对于一个特定的XML文档而言,其正确性分为两个层次。首先是其格式应该符合XML的基本格式要求,比如第一行要有声明,标签的嵌套层次必须前后一致等等,符合这些要求的文件,就是一个合格的XML文件,称作well-formatted。但除此之外,一个XML文档因其内容的不同还必须在语义上符合相应的标准,这些标准由相应的DTD文件或者Schema文件来定义,符合了这些定义要求的XML文件,称作valid。
因此,解析器也分为两种,一种是验证的,即会跟据XML文件中的声明,用相应的DTD文件对XML文件进行校验,检查它是否满足DTD文件的要求。另一种是忽略DTD文件,只要基本格式正确,就可以进行解析。
&验证的解析器通常都是比较重量级的。TinyXml不支持验证,但是体积很小,用在解析格式较为简单的XML文件,比如配置文件时,特别的合适。
查询速度的问题不在于XML,而在于存储XML的方式。如果是普通的文件方式,xml不适合很大数量数据的处理。比如,如果xml文件超过10M,你就必须采用SAX来处理,XMLDOM就没有办法了,但如果你存储在XML数据库里,则就要看该数据库对XML查询的支持和优化程度。
xml文件如果比较深,遍利的时间就长,可以从算法上考虑,也可以从xml文件设计上考虑。& 当然更推荐用SAX,他只把需要的内容加载到内存,这样检索的速度快了,DOM需要把整个xml文件加载到内存。
Visual Graph是一个矢量图控件,整个 Visual Graph 文件是 XML 文档格式,程序员可以把文件存放在数据库中,进行读写。 每个图形也有自己的XML格式,可以单独存取。&图形和图库是统一的XML格式,便于传输、存储和维护,支持WEB开发.采用图形文档和图库文档统一的 XML 格式,你可以任意自由地画图,任意设计属性、函数、事件,这样相当于给图形赋予了生命,设计好的图形文件马上就可以被当作图库来使用,这样通过多层嵌套,就可以设计非常复杂的图形出来,这样紧凑的结构、巧妙的设计,这是一种二维矢量绘图工具,这是一种面向对象的脚本编程语言。应用于电力行业,图形拓扑,矢量绘图,工控仿真等。
& Xerces & &
& 参考网站:http://xml.apache.org/xerces-c/ & &
& Xerces-C++ & 是一个非常健壮的XML解析器,它提供了验证,以及SAX和DOM & API。XML验证在文档类型定义(Document & Type & Definition,DTD)方面有很好的支持,并且在2001年12月增加了支持W3C & XML & Schema & 的基本完整的开放标准。 & &
& XMLBooster & &
& 参考网站:/'&/ & &
& 这个库通过产生特制的parser的办法极大的提高了XML解析的速度,并且能够产生相应的GUI程序来修改这个parser。在DOM和SAX两大主流XML解析办法之外提供了另外一个可行的解决方案。 & &
& Pull & Parser & &
& 参考网站:http://www.extreme.indiana.edu/xgws/xsoap/xpp/'&http://www.extreme.indiana.edu/xgws/xsoap/xpp/ & &
& 这个库采用pull方法的parser。在每个SAX的parser底层都有一个pull的parser,这个xpp把这层暴露出来直接给大家使用。在要充分考虑速度的时候值得尝试。 & &
& Xalan & &
& 参考网站:http://xml.apache.org/xalan-c/ & &
& Xalan是一个用于把XML文档转换为HTML,纯文本或者其他XML类型文档的XSLT处理器。 & &
& CMarkup & &
& 参考网站:/xml.htm'&/xml.htm & &
& 这是一种使用EDOM的XML解析器。在很多思路上面非常灵活实用。值得大家在DOM和SAX之外寻求一点灵感。 & &
& libxml++ & &
& http://libxmlplusplus.sourceforge.net/ & &
& libxml++是对著名的libxml & XML解析器的C++封装版本&& Xerces & c++ & --Apache的XML项目, & 但 & 只支持少数的字符编码,如ASCII,UTF-8,UTF-16等, &
& 不能处理包含中文字符的XML文档 &
& 但中文问题也是可以解决的。 &
& 1. & 背景介绍 &
& apache的xerces & c++是广大c/c++程序员非常喜欢使用的xml解析器之一。主要原因是其本身是一个开放源代码的项目而且提供不同平台下的库和源代码,故深受广大c/c++程序员的欢迎。 &
& xerces & c++可以到以下网站下载: &
& 1) & http://xml.apache.org/ & &
& 2) & /tools &
& & 2. & 问题描述 &
& 根据软件开发的要求,作者开发了一个文件特征识别软件,该软件可根据文件特有的特征识别出文件的类型。要求将文件特征保存在xml文件中。根据要求作者选择了xerces & c++作为xml解析器。但发现出了一个严重的问题:被解析的xml文件中不能包含中文,否则中文将不能正确的解析。作者研究了xerces & c++提供的例子程序,发现这些例子程序解析的结果也是错误的。只有domprint程序例外。这肯定了xerces & c++本身是支持中文的。 &
& xml编码: & &
& &pdf & ext=&pdf& & description=&pdf文档&& & & &magic & offset=&0& & type=&string& & value=&\x25\x50\x44\x46& & /& & &/pdf&saxprint程序解析结果: &
& &pdf & ext=&pdf& & description=&pdf文档&& & & &magic & offset=&0& & type=&string& & value=&\x25\x50\x44\x46&&&/magic&&/pdf&为此,作者曾经在ibm的中文网站发现一篇文章《如何利用xerces-c++解析包含中文字符的xml文档》并将其所描述的办法应用到程序中。但后来由于机器发生故障,硬盘上的数据全部丢失。不得不把以前做过的事重做一遍。因一时在ibm的网站上未找到上面提到的贴子,而且由于当时捡现成的没有用心研究其实现方法,故不得不仔细分析xerces & c++提供的源代码,自己动手解决中文问题。为了今后广大c++程序员碰到类似问题时不会像我一样痛苦。我也决定将自己的研究结果公布出来供大家分享。如果谁有更好的解决办法不要忘记告诉我。 &
& & 3. & 原因分析 &
& 上面的例子里,程序将&文档&两个中文字符解析成了乱码。但domprint程序确能够正确解析。这表明xerces & c++对国际编码肯定是支持的。作者通过对domprint和saxprint两个程序的比较跟踪发现问题的根本就是xmlformatter设置的问题。由于sax是基于事件的,大多数使用者只是简单的解析xml文档,xmlformatter的使用比较麻烦。而domprint也是通过标准的输出程序输出的屏幕上的,我们不能直接使用输出结果。 &
& 由于xml解析器解析的字符串都是xmlch格式的,一个字符占用一个字节,而汉字字符确要占用两个字节。故若不做适当的转换,汉字的输出结果就变成乱码了。 &
& & 4. & 解决办法 &
& 找到原因就有解决问题的方法了,明显的需要一个把解析出来的xmlch转换成普通的字符串。这是解析,如果我们需要自己写入xml文档也有一个把普通字符串转换为xmlch的过程。我把这两个转换过程封装在了一个名为&xmlstringtranslate&的类中。使用如下: &
& void & saxmagichandlers::startelement(const & xmlch* & const & name,attributelist& & attributes){ xmlstringtranslate & stringtranslate(&gb2312&); string & strname=stringtranslate.translate(name);//得到可包含汉字字符的普通字符串 string & strvalue=&pdf文档&; xmlch & * & value= & stringtranslate.translate(strvalue.c_str());//将普通字符串转换成xmlch串}采用xmlstringtranslate后的实际运行结果: & &
& &pdf & ext=&pdf& & description=&pdf文档&& & & &magic & offset=&0& & type=&string& & value=&\x25\x50\x44\x46&&&/magic&&/pdf&特别说明: &
& 由于为了防止内存释放问题,将普通字符串转换成xmlch & *的translate函数返回的是类的一个成员变量,故下面的代码是不允许的: & &
& xmlch & * & value1= & stringtranslate.translate(&测试1&);xmlch & * & value2= & stringtranslate.translate(&测试2&);这样使用的结果是value1和value2的值将是一样的(因为其内存地址根本就是一样的)。正确的使用方法是通过内存拷贝或则其他方法,将value1的值保存起来或则及时使用,否则value2将影响value1的值。
除了 & Xerces & ,还可以考虑 & MS & 的 & MSXML:: &
& VC使用MSXML解析XML文档 &
& & & & & & 现在XML文档应用的方面特别的多. &
& & & & & & 我把以前写过的一个例子帖出来,以备以后使用. &
& & & & & & 第一部分:DOM解析: &
& & & & & & 概述:DOM解析将会把一个完整的XML文档读进来,生成一个结构树。这样会要把XML文档全部都加载到内在中。所以解析起来的速度会要慢一些。 &
& & & & & & 1、如何加载xml文件: &
& & & & & & & & & & //创建DOM,加载XML文档 &
& & & & & & & & & & MSXML::IXMLDOMDocumentPtr & pCommandD &
& & & & & & & & & & pCommandDoc.CreateInstance(__uuidof(MSXML::DOMDocument)); &
& & & & & & & & & & & pCommandDoc-&put_async(VARIANT_FALSE); &
& & & & & & & & & & & pCommandDoc-&put_validateOnParse(VARIANT_FALSE); &
& & & & & & & & & & & pCommandDoc-&put_resolveExternals(VARIANT_FALSE); &
& & & & & & & & & & & pCommandDoc-&put_preserveWhiteSpace(VARIANT_TRUE); &
& & & & & & & & & & & pCommandDoc-&load(file.GetBuffer(0)); &
& & & & & & 2、在XML文档中查找指定的结点: &
& & & & & & & //找到 &
& & & & & & MSXML::IXMLDOMNodePtr & pRootNode=pCommandDoc-&selectSingleNode(&root/record&); &
& & & & & & & & if & (pRootNode==NULL) &
& & & & & & { &
& & & & & & & & & & & return & ; &
& & & & & & & } &
& & & & & 3、得到XML文档中,结点的属性 &
& & & & & & & & & CString & strT &
& & & & & & MSXML::IXMLDOMNamedNodeMapPtr & pAttrs & = & NULL; &
& & & & & & pRootNode-&get_attributes(&pAttrs); &
& & & & & & if & (pAttrs==NULL) &
& & & & & & { &
& & & & & & & & & & & &
& & & & & & } &
& & & & & & 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解析 &
& & & & & & 概述:SAX使用的是加载式的,将会把XML文档分断,加载到内存中。使用事件通知的方式,来表示找到结点。好像没有写文档的能力吧。它的速度要比DOM快不少。 &
& & & & & & 使用SAX的时候,就需要重载MSXML4.0中的一个接口ISAXContentHandler。 &
& & & & & & 有几个函数重载了之后,当找到了结点之后,就会回调这一些函数。&&
了这篇文章
类别:┆阅读(0)┆评论(0)
16:03:14 16:39:48}

我要回帖

更多关于 域名解析默认端口 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信