`
h_rain
  • 浏览: 121566 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
文章分类
社区版块
存档分类
最新评论

使用Dxpcom进行HTML文本的DOM解析

阅读更多
    开帖纪念,dxpcom终于可以使用了.
    找了好半天,才知道怎么使用mozilla xpcom进行HTML的DOM解析.
    解析使用的组件是"@mozilla.org/xmlextras/domparser;1",可以解析HTML和XML.解析使用的接口是nsIDOMParser.
    代码如下,保存时要注意为UTF-8格式,不然无法用DMD编译.
import mozilla.xpcom.nsXPCOM;
import mozilla.xpcom.nsIDOMParser;
import mozilla.xpcom.nsIComponentManager;
import mozilla.xpcom.nsIDOMDocument;
import mozilla.xpcom.nsIDOMHTMLDocument;
import mozilla.xpcom.nsISupports;
import mozilla.dxpcom.StringAPI;
import mozilla.dxpcom.QueryInterface;
import std.string;
import std.stdio;

void main(char[][] args)
{
    //定义xpcom组件管理器接口
	nsIComponentManager componentManager;
	nsresult result;
    //定义一个临时使用的空串
    AString tStr=new AString();

	//初始化xpcom环境
	result = NS_InitXPCOM2(null, null, null);
	assert(result==0);

	//得到xpcom组件管理端接口
	result = NS_GetComponentManager(&componentManager);
    assert(result==0);

    //定义DOM解析器接口
	nsIDOMParser DOMParser;

	//使用xpcom组件管理端,从指定的组件中得到指定的接口
	result = componentManager.CreateInstanceByContractID("@mozilla.org/xmlextras/domparser;1",null,
		&nsIDOMParser.IID,cast(void**)&DOMParser);
    assert(result==0);

    //定义待解析的HTML文本串
	PRUnichar HtmlStr[]=r"<html><head><title>test_title</title></head><body><al>test</al></body></html>"w;

    //定义DOM文档对象接口
	nsIDOMDocument DOMDoc;

    //使用DOM解析接口解析html文本串,得到DOM文档对象接口
    result=DOMParser.ParseFromString(cast(PRUnichar*)HtmlStr,"application/xhtml+xml",&DOMDoc);
    assert(result==0);
    DOMParser.Release();

    /*
    //得到文档的类型
    nsIDOMDocumentType DocType;
    result=DOMDoc.GetName(&DocType);
    assert(result==0);
    result=DocType.GetInternalSubset(cast(nsAString*)tStr);
    assert(result==0);
    writefln("Doc Type=: %s", tStr.GetString());*/

    //定义DOM节点列表接口
    nsIDOMNodeList NodeList;

    //定义待解析得到的节点的名字
    AString TagName = new AString("title"w);
    //解析得到节点列表
    result=DOMDoc.GetElementsByTagName(cast(nsAString*)TagName,&NodeList);
    assert(result==0);

    //定义DOM节点接口
    nsIDOMNode Node;
    uint Len=0;

    //判断节点列表是否为空
    result=NodeList.GetLength(&Len);
    assert(result==0&&Len!=0);

    //从节点列表中得到一个节点
    result=NodeList.Item(0,&Node);
    assert(result==0);
    NodeList.Release();

    //得到这个节点的名字
    result=Node.GetNodeName(cast(nsAString*)tStr);
    assert(result==0);

    //显示这个节点的名字
    wchar wStr[]=tStr.GetString();
    Len=wStr.length;
	writefln("Node Name =: %s", wStr);

    //再定义一个节点接口,用于表示子节点
    nsIDOMNode cNode;

    //得到这个节点的子节点
    result=Node.GetFirstChild(&cNode);
    assert(result==0);


    //得到子节点的值
    result=cNode.GetNodeValue(cast(nsAString*)tStr);
    assert(result==0);
    cNode.Release();

    //显示这个子节点的值
    wStr=tStr.GetString();
    writefln("Node Value=: %s", wStr);

    //释放所有用过的接口
    Node.Release();
    DOMDoc.Release();
    componentManager.Release();
    //关闭xpcom环境
	result = NS_ShutdownXPCOM(null);
	assert(result==0);
}




看上去好像很繁琐,但等D的异常风格包装完事后,会好看的多!

再次对qiezi的工作表示敬意!为我们提供了在D中使用xpcom的可能!
:)

其他不明的相关事宜,请大家讨论.

这次修改,加入了Release调用.

最终的运行结果是:
Node Name =: title
Node Value=: test_title
分享到:
评论
11 楼 qiezi 2007-04-27  
现在异常封装在调用的时候就是这样的:
void InitWithPath(wchar[] path)
{
    scope auto _path = new AString(path);
    nsresult result = inner.InitWithPath(cast(nsAString*)_path);
    CheckException(result);  // 如果不是NS_OK则抛出异常
}

这是一个异常风格+D风格包装的例子,完成了几个工作,一是参数类型从nsAString*换成wchar[] path,二检查异常。在一些更复杂的例子里,可能还有接口类型到外覆类型的转换、返回值转换(原来是把返回值生成一个out参数,异常风格将转换成和IDL形式一样的返回值)、数组参数转换(C++版本是转成2个参数)。

这里说的异常风格指的是CheckException检查异常,其实更多的工作应该是D风格的转换,以后统一称为D风格算了。。
10 楼 DavidL 2007-04-27  
没看代码,我不知道异常的封装是什么样的,听你这么说,如果xpcom设计成异常情况抛出异常就好了。
9 楼 qiezi 2007-04-27  
引用计数是肯定要的,析构时调用Release说的是我们的D包装类,因为接口是没有析构的。你说的循环release我没看懂,指的是用D写XPCOM组件时要做的吗?一般对象引用计数大于0时不会析构,这可能需要找个地方做个引用呢。

COM或XPCOM一般不讲究是否继承,而是是否提供某接口,所以具体实现的部分可能根本没有继承。你上面这个具体的例子也只有查文档才知道了。现在测试主要测一下nsISupports里面的三个方法,还有一些nsXPCOM里面的方法,接口部分找几个测一下就可以了,全部测试工作量比较大。
8 楼 h_rain 2007-04-26  
在自动管理release的时候,最麻烦的就是要再管理一个外部的引用计数,这样在申请的时候,AddRef,这个计数就++;在析构的时候,循环release,计数--。(这样能实现吗?)

另外,我今天在进行测试的时候,想将nsIDOMDocument接口转换为nsIDOMHTMLDocument接口,就是用nsIDOMDocument.QueryInterface查询得到nsIDOMHTMLDocument,但失败了,我在做ie的HTML控制的时候,就这么类似的用过,不知道为什么xpcom不能这么做。
nsIDOMHTMLDocument是继承自nsIDOMDocument的。

现在应该是需要比较多的测试才能发现所有转换引起的问题,这个是比较麻烦的...
7 楼 qiezi 2007-04-26  
工具类和模板暂时不要全部转过来吧,不一定都能用上,到时候看缺哪些就转哪些,纯工具转的也不咋好。
6 楼 qiezi 2007-04-26  
目前正在做的应该算是异常风格+D风格吧,新加的一些接口中有许多使用了一些C++里面的类型,这里称为native类型吧,这些比较难处理一些,目前我的办法是不处理它,编译用alias void*来定义,它们的外覆类都是VoidClass,什么也不做,占个位置,先把代码生成出来,不然不能继续了。另一个是数组,idl显然偏向于C++,所以数组类型在idl里面定义时有2个参数名称,这个转换也有点麻烦。好在现在只要把xpidl修改好了就可以把所有代码生成出来,所以工作量说起来也不算大,只是各种问题太多了些,没办法计算出所需要的时间亚。

目前CheckException还空着呢,有许多错误码要转成异常类型,这部分工作量也有点大,但比较独立,有时间可以看看这个。异常风格的包装对象在析构时会调用Release的,但又要防止重复Release,
5 楼 h_rain 2007-04-26  
呵呵,刚才匆忙写上了就跑了。
我正想说,是不是在接口使用完毕后需要release。
明天有空把release给补上:)

qiezi,就等着D风格的包装了呢,哈哈。

关于接口的引用计数,在D风格包装里面,能实现自动管理吗?
看xpcom,里面好像还有很多的工具类与模板,这些是不是得手动修改过来啊?

to DavidL:
异常封装的里面其实也是需要有一个if然后抛出异常的,所以效率与上面相比,不会高到哪里去,就是在写代码的时候,不需要如此频繁的检查操作结果了。:(

4 楼 DavidL 2007-04-26  
就我个人观点,异常封装应该成为唯一接口,这样运行效率最高,因为不发生异常占大多数情况。
3 楼 qiezi 2007-04-26  
异常风格代码将只有你上面的1/3左右,因为你这里还使用断言检查了返回值,异常风格不需要这个,而还有的精简则是字符串、out参数、返回值等,都可以简化。

目前这个版本已经基本上可以达到编写、调用XPCOM,编写可能会有一些小问题,比如AddRef/Release后如何处理对象的释放问题,暂时还没时间考虑它,可以参考D里面ComObject的实现,它在Release后是不释放的,等到下次GC时才释放。不过细节上可能要考虑一下,有时间可以看看能不能编写。
2 楼 oldrev 2007-04-26  
还差一个 ATL,呵呵
1 楼 qiezi 2007-04-26  
一般正常的流程,在QueryInterface成功时会自动调用AddRef,调用完成以后要Release,否则也算是资源卸漏吧。

所以在NS_ShutdownXPCOM之前调用各个已经获取对象的Release应该是个好习惯,具体情况还要进行测试。

相关推荐

    dom解析和sax解析

    DOM(Document Object Model)解析和SAX(Simple API for XML)解析是两种常见的XML文档解析方式,它们在处理XML数据时有不同的策略和优缺点。 DOM解析是一种基于树型结构的XML解析方法。当一个XML文档被DOM解析器...

    simple_html_dom,php下的html文件DOM解析库

    4. 对于性能要求较高的场景,可能需要考虑使用更底层的DOM解析库,如DOMDocument。 总结,PHP Simple HTML DOM解析库为PHP开发者提供了一种高效、灵活的HTML处理方式,无论是简单的数据提取还是复杂的页面重构,都...

    HtmlDom解析组件(C#)

    在.NET框架中,使用HtmlAgilityPack这个开源库可以方便地对HTML进行DOM解析。HtmlAgilityPack是一个强大的工具,能够处理不规范的HTML,它提供了灵活的DOM模型,使得开发者可以轻松地遍历、修改或提取HTML文档中的...

    PHP Simple HTML DOM解析器使用入门

    ### PHP Simple HTML DOM 解析器使用入门 #### 一、简介 在Web开发领域,解析HTML文档是一项常见的任务。PHP Simple HTML DOM Parser是一款强大的库,它简化了这一过程,使得开发者能够更加高效地处理HTML文档。该...

    html文本解析器(DOM)

    HTML文本解析器,通常指的是DOM解析器,是Web开发中不可或缺的一部分。DOM,全称Document Object Model,即文档对象模型,是一种W3C标准,它为HTML和XML文档提供了一个结构化的表示,并定义了访问和操作这个结构的...

    Android Dom解析XML

    DOM解析器读取XML文件并构建一个内存中的节点树,其中每个元素、属性、文本等都对应一个节点。在Android中,我们通常使用`javax.xml.parsers.DocumentBuilderFactory`来创建解析器,并通过`DocumentBuilder`实例解析...

    DOM解析XML文件例子

    在这个例子中,我们将深入探讨如何使用DOM解析XML文件,以理解和掌握XML文档的结构,并进行数据提取、修改和创建。 首先,XML(Extensible Markup Language)是一种标记语言,用于存储和传输数据,具有自描述性和...

    dom解析器 动态修改当前页面

    使用DOM解析器动态修改当前页面的方法主要包括以下步骤: 1. **获取DOM对象**:首先,你需要通过JavaScript或者其他支持DOM的编程语言获取到目标元素的引用。例如,JavaScript中的`document.getElementById`或`...

    java平台中使用DOM解析xml文件

    5. **遍历和操作XML结构**:现在,你可以使用DOM API遍历XML文档的节点,获取或修改元素、属性和文本。 ```java NodeList nodeList = doc.getElementsByTagName("tag_name"); for (int i = 0; i (); i++) { ...

    使用dom4j 和本地dom 解析xml 文件

    - 解析后得到`Document`对象,可以使用DOM4J的API进行操作,如`selectNodes()`, `element()`, `text()`等。 - DOM4J还支持XPath表达式,可以通过`XPathFactory`和`XPath`对象来选择XML节点。 在实际应用中,DOM4J...

    html-dom-parser:HTML到DOM解析器

    html-dom-parser 在服务器(Node.js)和客户端(浏览器)上均可使用HTML到DOM解析器: HTMLDOMParser(string[, options])解析器将HTML字符串转换为描述DOM树JavaScript对象。例子const parse = require ( '...

    php dom 解析类和函数文件封装

    2. **HTML解析与操作**:使用`simple_html_dom`,你可以方便地进行以下操作: - 查找元素:通过CSS选择器或者元素属性查找元素。 - 修改元素:替换、添加或删除元素和属性。 - 遍历元素:通过递归遍历DOM树,访问...

    android Dom解析xml文件

    在Android中,我们主要使用Java的标准库`javax.xml.parsers.DocumentBuilderFactory`和`org.w3c.dom.Document`来实现DOM解析。这些库提供了创建DOM解析器、解析XML文件和操作XML节点的功能。 ### 3. 实现步骤 ####...

    DOM解析xml文件实例讲解

    在Android开发中,DOM(Document Object Model)解析是处理XML文档的一种常见方法,它提供了一种结构化的表示XML文档的方式,并允许开发者通过编程接口与XML数据进行交互。本篇文章将深入探讨DOM解析XML文件在...

    java dom 解析 xml 实例

    Java DOM 解析 XML 实例是 Java 语言中常用的 XML 解析方法之一,使用 W3C 推荐的文档对象模型(Document Object Model,DOM)来解析 XML 文档。DOM 提供了一个树形结构的对象模型,通过遍历树形结构可以访问和操作 ...

    java_dom解析xml xml java

    标题“java_dom解析xml xml java”表明了本文档的主题是关于如何使用Java中的DOM技术来解析XML文件。 #### 描述分析 描述中提到这是一个适合新手入门的内容,并给出了一个简单的XML示例。该XML文档包含了一个`...

    DOM解析XML应用实例(入门经典案例)

    DOM解析XML时,会将整个XML文档加载到内存中,形成一棵由节点构成的树形结构,每个节点代表XML文档的一部分,如元素、属性、文本等。 首先,了解DOM解析的基本步骤: 1. 加载XML文档:使用Java的`...

    android上使用DOM解析XML

    在Android 4.0及以上版本,我们可以使用内置的Java XML DOM API来实现XML解析。下面将详细介绍在Android中使用DOM解析XML的基本步骤和关键知识点。 1. **导入XML解析库** 在Android项目中,我们不需要额外导入库,...

    项目中使用到的解析html富文本

    本篇文章将深入探讨在项目中使用HTML富文本解析的相关知识点。 一、HTML基础知识 HTML(HyperText Markup Language)是一种标记语言,用于构建和组织网页结构。HTML元素由标签构成,这些标签定义了文本的样式、布局...

Global site tag (gtag.js) - Google Analytics