`
h_rain
  • 浏览: 121571 次
  • 性别: 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
分享到:
评论
31 楼 h_rain 2009-06-27  
karlzheng 写道
请问楼主:import mozilla.xpcom.nsXPCOM 的库从哪里得来的?

http://code.google.com/p/dxpcom/
这是当时qiezi发起的一个项目,目前基本停滞了.
因为xpcom也没有一个稳定的发布版本,变动太大了,文档不全.
30 楼 karlzheng 2009-06-15  
请问楼主:import mozilla.xpcom.nsXPCOM 的库从哪里得来的?
29 楼 qiezi 2007-04-28  
用browser太浪费了吧。。看一下firefox源代码是怎么使用的。。
28 楼 h_rain 2007-04-28  
都试过了,这个东西在文档上就说了,应该只能解析XML,不能解析HTML.
我打算使用Browser试试吧.
麻烦.
27 楼 qiezi 2007-04-27  
应该不用显式地指定nsIDOMHTMLDocument,使用"text/html"作为XML的类型试试。
26 楼 qiezi 2007-04-27  
操作HTML应该用nsIDOMHTMLDocument吧。
25 楼 h_rain 2007-04-27  
再次仔细看了Mozilla的文档,上面说,nsIDOMParser.ParseFromString只能解析标准的XML DOM
...........

看来,还得找其他的组件来解析HTML了...
24 楼 h_rain 2007-04-27  
想用上面的代码解析一个大点的文件,结果却发现了问题:
有<script></sctipt>的时候,好像就不好使.
<html>

<head>
	<title>test</title>
</head>

<body topMargin="0">
	<table width="100%"></table>
</body>

</html>

再发现,上面的代码也不行,好像不认识table!!

狂晕...
23 楼 h_rain 2007-04-27  
C++接口风格,D接口风格,那就这么定了吧.

D风格里面,对象的复制也是单个对象自己管理自己的引用吧?
这么看确实,nsISupportsD好像就不用再提供AddRef和Release了.
22 楼 qiezi 2007-04-27  
D风格的nsISupportsD好像就不用再提供AddRef和Release了亚,它的构造函数里接受了一个nsISupports对象,接受时已经是从QueryInterface里AddRef过的,所以只需要在nsISupportsD的析构函数里调用Release就行了。只有进行对象拷贝时才需要显式地调用inner.AddRef和inner.Release。D对象的clone是怎么调用的?我还没用过呢。
21 楼 qiezi 2007-04-27  
Native接口风格好长啊,而且这么也显得好像D不够Native似的。干脆叫C++接口风格和D接口风格算了,反正也确实是这么回事。。
20 楼 qiezi 2007-04-27  
就这么称呼吧。

是不是有黑幕,还是要看一下源码亚,我只是觉得奇怪,如果没有黑幕,它如何知道对象是不是该释放呢?

DMD代码里有许多地方都有COM类型判断,我怀疑就在某处,有时间找找看。
19 楼 h_rain 2007-04-27  
晕~
我讨厌黑幕...
:)
18 楼 h_rain 2007-04-27  
现在是该好好的定一下称呼了.
那就把目前我的这个例子中的dxpcom接口风格称为"dxpcom的Native接口风格",把待最终实现的D风格包装的接口称为"dxpcom的D接口风格"怎么样?
17 楼 qiezi 2007-04-27  
调用XPCOM时,多次调用AddRef或者是过多或过少调用Release都是错误的,使用上的错误不能完全避免。我建议是QueryInterface调用AddRef,包装类的析构里面调用Release,其它地方不调用这2个就不会有麻烦。

用D写XPCOM时,只需要找一个全局的地方保存对象引用防止被GC掉,在引用计数归0时去掉引用就行了,下次GC的时候自然会释放掉,ComObject是这么做的,不过只看到它处理引用计数,没有一个全局的保存对象的东西,那么GC是如何判断该释放掉对象?莫非这方面在DMD里面也有类似IUnknown这样的黑幕?
16 楼 h_rain 2007-04-27  
"析构时调用Release说的是我们的D包装类"
我说的也是这个,但如果担心AddRef被反复调用,而导致最终无法正常释放的话,就应该需要一个引用计数,在析构函数里面循环Release.

当然了,如果不提供这个功能的话也是可以的,只是需要程序员仔细的使用AddRef或不使用.
15 楼 qiezi 2007-04-27  
上面的各个D包装类型后面要加上D的,nsIDOMNode生成出来的是nsIDOMNodeD。
14 楼 qiezi 2007-04-27  
容器类型应该是可以加上opApply的,不过修改idl应该是不行,会造成其它语言兼容问题,修改生成的代码也不好,下次重新生成又要修改,有什么好的办法呢?

还是采取打补丁的方式?像这样:

if classname == "nsIDOMNodeList"
  generate_opapply("nsIDOMNode", "length", "item");


如果当前接口是nsIDOMNodeList,就产生一个opApply:

void opApply(void delegate(uint, nsIDOMNode) dg)
{
    for(uint _i=0; _i<Length; ++_i)
    {
        nsIDOMNode node = Item(_i);
        dg(_i, node);
    }
}
13 楼 qiezi 2007-04-27  
引用
最好把只有一个参数的函数转换为使用返回值

应该是只有一个out参数并且返回类型是void吧,这是idl写的不好造成的。实现应该是可以的。
12 楼 oldrev 2007-04-27  
最好把只有一个参数的函数转换为使用返回值

相关推荐

    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