IE 解析 Web Page DOM结构 (二) - wallaceli1981的专栏 - CSDNBlog

来源:百度文库 编辑:神马文学网 时间:2024/05/03 13:49:26
 IE 解析 Web Page DOM结构 (二)
新一篇: C++ STL轻松导学
接下来的两篇我将介绍怎样从DOM流中解析出组成网页的最基本的两种元素:文字和图像。
上一篇我说过网页是由许多嵌套的frame组成,而每一个frame都是一个独立的单元,他们包含自己的文字和图片。解析文字和图片有以下两种情况:
1.         他们都直接放置在网页“BODY”层,此时我不用考虑这些frame导致的布局影响。这是最简单的一种情形。
2.         而常见的情形是他们被放置于嵌套的frame中,比如Button控件上的文字,TextBox控件中的文字等。
l   文字
1.    “BODY“层的文字
文字在DOM语言中有好多种标签可以代表他,比如Label,Title,和Anchor等等。他们都表示有文字。
·         首先,我需要得到文字的位置以及他的本体文字,这可一从IHTMLElement接口中获得。
IHTMLElement Members(从MSDN摘录的片段)
offsetParent
Retrieves a reference to the container object that defines the IHTMLElement::offsetTop and IHTMLElement::offsetLeft properties of the object.
offsetHeight
Retrieves the height of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.
offsetLeft
Retrieves the calculated left position of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.
offsetParent
Retrieves a reference to the container object that defines the IHTMLElement::offsetTop and IHTMLElement::offsetLeft properties of the object.
offsetTop
Retrieves the calculated top position of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.
offsetWidth
Retrieves the width of the object relative to the layout or coordinate parent, as specified by the IHTMLElement::offsetParent property.
innerText
Sets or retrieves the text between the start and end tags of the object.
下面是可行的伪代码:
long ltop, lleft, lHeight, lwidth;
hr = spElement->get_offsetLeft(&lleft);
hr = spElement->get_offsetTop(<op);
hr = spElement->get_offsetHeight(&lHeight);
hr = spElement->get_offsetWidth(&lwidth);
BSTR bstrInnerText;
hr = spElement->get_innerText(&bstrInnerText);
·         关于文字的字体风格,如字体大小,字体族,是否加粗,倾斜等等,我就只能从CSS流中解析。而CSS流的代表接口就是IHTMLCurrentStyle。
IHTMLCurrentStyle Members(从MSDN摘录的片段)
fontFamily
Sets or retrieves the name of the font used for text in the object.
fontSize
Sets or retrieves a value that indicates the font size used for text in the object.
fontStyle
Sets or retrieves the font style of the object as italic, normal, or oblique.
fontVariant
Sets or retrieves whether the text of the object is in small capital letters.
fontWeight
Sets or retrieves the weight of the font of the object.
下面是可行伪代码:
CComQIPtr spElement;
CComQIPtr spElement2(spElement);
CComQIPtrspCurrentStyle;
spElement2->get_currentStyle(&spCurrentStyle);
VARIANT  varfontSize;
varfontSize.vt = VT_BSTR;
spCurrentStyle->get_fontSize(&varfontSize);
VARIANT varfontWeight;
varfontWeight.vt = VT_BSTR;
spCurrentStyle->get_fontWeight(&varfontWeight);
VARIANT varHeight;
varHeight.vt = VT_BSTR
spCurrentStyle->get_height(&varHeight);
这里你所取得的fontFamily的值是一个字体族列表,其中的每个字体族用分号隔开以防止当有多种字体族混杂在一起。此值主要由两部分组成:字体族名称和通用字体族名称。如果字体族名称包含空白符,它应该出现一个或两个引号;通用字体族名称不用包含在引号中。
为什么要这样组织字体族名称呢?这主要是因为你不知道客户端安装了什么字体, 你应该提供用户一个备用的字体族 – 通用字体族名称在字体族名称列表的末尾,防止如果客户端没有安装字体族名称指定的字体时,可以用通用字体族名称来替代。
这个字体族名称列表也可以包含嵌入字体。此外,关于fontFamily的默认值可以通过Microsoft Internet Explorer->Internet Options menu->General tab->Fonts button来设置。
综上所述,IE浏览器是这样来应用字体的:首先他会从DOM中解析出fontFamily的字体列表,然后他会尝试其中的每一个字体,直到找到一种客户端已经安装的字体族。如果到列表末尾,IE浏览器依然没有找到相应的字体,那么他就会使用IE设置的那个默认字体。
此外,在上面的伪代码中所得到的字体大小,高度,宽度等数据,他们返回的值有可能不是绝对的数值,如8pt。相反,它可能是一种相对值(相对上一层字体),比如:xx-small,x-small,larger,smaller等等。这不可避免地要求我们自己将这些抽象概念转化为绝对数值。特别是,如果给出的是百分比,我们可能需要递归算出这些数值。
最糟糕的是,有时候你可能取得的是负值,比如:“-1”,“-2”。这意味着字体大小必须转化为设备单位,而且匹配它的绝对数值通过可用字体字符的高度。
·         文字颜色是个很麻烦的问题,可以用下面的代码:
CComQIPtrspCurrentStyle;
VARIANT varColor;
varColor.vt = VT_BSTR|VT_I4;
spCurrentStyle->get_color(&varColor);
但是请注意返回的varColor是一个BSTR值,而且是专属于网页设计的一组颜色值,如果你想使用RGB颜色值,必须自己进行转换。而且,DOM常常会简写这个颜色值,比如#00ccff,从上面的代码取出来的值可能是#0cf。
·         文字编码问题
我们可以在IE浏览器中设置网页的编码,这些信息我们也可以从DOM中获取.
BSTR bstrCharset;
spHTMLDocument2->get_charset(&bstrCharset);
2.    嵌套容器中的文字
我打算以Table控件中的文字为例,其他控件容器中的文字可以按类似的方法来处理
·         Get text in Table
许多网页中都有Table控件,每个Table都有自己的文字。比如,下面这个Table:
Hanna Strategies, Ltd. is among the first software outsourcing service providers in China ‘s IT industry, specializing in the research and development of computer aided design (CAD) and data management software......
这个Table的DOM树如下所示:(通过IE Dev Toolbar取得)
·         文字分行
网页中的文字是没有分行符让你判断文字该到哪个字分行,这是一个大麻烦,尤其对于那些做文件格式转化的程序员而言。因为这意味着虽然你可以得到上面的那一大段文字,但是,你不知道怎么来断行。唯一可行的办法就是自己设计算法来分行,但只是一件非常复杂的事。
你想一想,你既要考虑字体目前的大小,还要调整Table一行是多宽,从而计算每一行最多可以放几个字。其中,还要加上字跟字,行跟行之间的间距值。这实在是个很烦琐的事。
·         Table中文字的位置
现在文字的位置需要考虑连个因素:一个是文字相对于Table的位置;另一个是整个Table相对于网页的位置。
IHTMLTable Members(从MSDN摘录)
align
Sets or retrieves a value that indicates the table alignment.
cellPadding
Sets or retrieves the amount of space between the border of the cell and the content of the cell.
cellSpacing
Sets or retrieves the amount of space between cells in a table.
height
Sets or retrieves the height of the object.
width
Sets or retrieves the width of the object.
IHTMLTableCell Members(从MSDN摘录)
colSpan
Sets or retrieves the number columns in the table that the object should span.
height
Sets or retrieves the height of the object.
noWrap
Sets or retrieves whether the browser automatically performs wordwrap.
rowSpan
Sets or retrieves how many rows in a table the cell should span.
vAlign
Sets or retrieves how text and other content are vertically aligned within the object that contains them.
width
Sets or retrieves the width of the object.
关于这一点我会在后面详细讨论,这也是一个浩大的解析过程。
IE 解析 Web Page DOM结构 (二) - wallaceli1981的专栏 - CSDNBlog IE 解析 Web Page DOM结构 (一) - wallaceli1981的专栏 - CSDNBlog IE 解析 Web Page DOM结构 (二) BOM结构 - Pascal的专栏 - CSDNBlog 2007年web开发技术预言 - Lanneret_Lv的专栏 - CSDNBlog The Semantic Web - chs version - 刀目村的专栏 - CSDNBlog The Semantic Web - eng version - 刀目村的专栏 - CSDNBlog The Semantic Web - eng version - 刀目村的专栏 - CSDNBlog some IQ problems zz form Web - 刀目村的专栏 - CSDNBlog 深入浅出理解索引结构 - dutguoyi(新鲜鱼排)的专栏 - CSDNBlog DOM SAX JAXP DOM4J JDOM xerces解析器 - 早晨的阳光的专栏 ... Effective Java 笔记(二) - ilibaba的专栏 - CSDNBlog 各大网站所用的操作系统与Web服务器 - yzc的专栏 - CSDNBlog 关于三种主流WEB架构的思考 - Haohappy的专栏--PHP5研究中心 - CSDNBlog 基于WEB应用开发的java程序员必备工具 - 辛佳雨的专栏 - CSDNBlog Deep Web(深层网络or深度网络) - funson的专栏 - CSDNBlog Linux操作系统的源代码目录树结构图解 - 软体疯子专栏 - CSDNBlog C armman的专栏 - CSDNBlog VC 中利用MSXML解析XML文档 - ChinaWash 专栏 - CSDNBlog 软件工程文档模板----二、项目开发计划 - lihuaidong521的专栏 - CSDNBlog 赛车游戏(二)一个Mascot Capsule v3多人游戏例子 - mobilechannel的专栏 - CSDNBlog AOP以及其在Spring中的应用(二) - hesan的专栏 - CSDNBlog Tapestry的介绍 - bfh365的专栏 - CSDNBlog CFileDialog的详解 - bhw1985的专栏 - CSDNBlog