使用xpath实现document.querySelector样式选择器进行html解析(四):将选择结果封装进行输出

本文主要是介绍使用xpath实现document.querySelector样式选择器进行html解析(四):将选择结果封装进行输出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用xpath实现document.querySelector样式选择器进行html解析(一):将html转成xml

使用xpath实现document.querySelector样式选择器进行html解析(二):扩展一下xpath以便支持正则

使用xpath实现document.querySelector样式选择器进行html解析(三):实现样式选择器

使用xpath实现document.querySelector样式选择器进行html解析(四):将选择结果封装进行输出

-----------------------------------------------------------------

恩,其实到目前为止,关于xpath解析html的样式选择器其实已经完工了,而且,应该说比预期的目的还多出了一丢丢的效果

例如:QuerySelector("*[style*='(?<!\w)font-weight\s*:\s*bold(?!\w)']"),可以选中所有style属性中包含粗体定义的节点

例如:QuerySelector("*:contains(abc.*?xyz)"),可以选中所有正文中包含abc和xyz,且abc在xyz之前的节点

注意到没有,我们可以直接使用正则,当然了,第三章我贴的伪类contains处理之前的那个正则不支持圆括号输入,关于指定属性的正则不支持方括号输入,自己魔改一下就可以完整的支持正则了,或者比较麻烦,需要层深计算,但还是可以实现的,可以参考文盲老顾之前关于正则的博文,但是个人感觉没什么必要了

本章为选择器的最后一章,关于结果输出方式的,有自己代码风格的可以不看,毕竟文盲老顾也是半路出家的c#工作者,没有考虑到的,没有学习到的东西都还很多,有更好的结果输出方案的也请告知文盲,让文盲继续进步哦

-----------------------------------------------------------------

为了方便得到结果之后直接可以用.连接属性,用来直接输出结果,所以QuerySelector方法我们修改一下
        public HtmlObjectResult QuerySelector(string selection){string xpath = CssParser.ParseCSS(selection);try{return new HtmlObjectResult(_xml.SelectNodes(xpath, XMLExpand.XPathExpand));}catch (Exception ex){throw ex;}}

直接将返回的XmlNodeList封装到一个类里,作为结果实现

    public class HtmlObjectResult{private List<HtmlObjectNode> _result = new List<HtmlObjectNode>();private int _curr = 0;public int Count{get{return _result == null ? 0 : _result.Count;}}public HtmlObjectNode[] NodeCollection{get{return _result.ToArray();}}public HtmlObjectNode Node{get{return _result == null ? null : _result[_curr];}}public HtmlObjectResult(XmlNodeList xnl){for (int i = 0; i < xnl.Count; i++){_result.Add(new HtmlObjectNode(xnl[i]));}}public HtmlObjectResult Next{get{_curr += _curr < _result.Count - 1 ? 1 : 0;return this;}}public HtmlObjectResult Previous{get{_curr -= _curr > 0 ? 1 : 0;return this;}}public HtmlObjectResult First{get{_curr = 0;return this;}}}

对于结果来说,它其实是一个节点集合,所以,提供一个Count,来表示到底有多少节点被选中

一般情况下,我们都是直接使用的第一个节点作为我们的结果,所以定义一个First,如果需要其他结果,可以用Next、Previous来选择不同的结果,恩,反正都是返回这个结果集本身,只是下标定位改变了而已

然后可以返回当前选中的结果作为输出内容,也就是Node属性,Node也是一个封装后的xml节点,稍后再讲

当然,如果不喜欢这些,可以直接输出所有的结果,NodeCollection可以满足你的需要,当然其中的元素也是被封装好的结果节点

再然后是正式输出我们期望的结果值了

    public class HtmlObjectNode{private XmlNode _node = null;public HtmlObjectNode(XmlNode node){_node = node;}public HtmlObjectNode Next{get{return _node == null ? null : _node.NextSibling != null ? new HtmlObjectNode(_node.NextSibling) : this;}}public HtmlObjectNode Previous{get{return _node == null ? null : _node.PreviousSibling != null ? new HtmlObjectNode(_node.PreviousSibling) : this;}}public HtmlObjectNode Parent{get{return _node == null ? null : _node.ParentNode != null ? new HtmlObjectNode(_node.ParentNode) : this;}}public string InnerHtml{get{return _node == null ? null : Regex.Replace(_node.InnerXml, @"<!\[CDATA\[|\]\]>", "", RegexOptions.IgnoreCase).Trim();}}public string OuterHtml{get{return _node == null ? null : Regex.Replace(_node.OuterXml, @"<!\[CDATA\[|\]\]>", "", RegexOptions.IgnoreCase).Trim();}}public string InnerText{get{return _node == null ? null : _node.InnerText;}}public XmlNode Node{get{return _node;}}}

作为被选中的节点,有时候我们需要纯文本内容,有时候需要html内容,html内容有时候需要包含节点本身,有时候不包含

所以,我们的结果输出就直接定义成三个,分别是InnerText、InnerHtml、OuterHtml,这个也符合html本身的习惯

由于我在第一章的时候,将html转成xml的时候还追加了不少的CDataSetion节点,这些节点在作为结果输出的时候应该被删除节点声明,所以我在这里用正则删除了一些信息

当然,有时候某些节点定位非常麻烦,可他相邻的部分节点非常好定位,那么我们通常会定位到我们希望选中的节点之前,例如有一个表格,很多行很多列,没有样式啦、ID啦,甚至数据的位置也可能改变,但表格的格式不变,比如每一个td声明数据名称后,下一个紧跟着的td必定是它对应的值的时候,我们就可以直接定位到这个数据名称的位置,例如 QuerySelector("td:contains(姓名)"),然后使用Next向后移动一个节点,再输出就是对应的值了:QuerySelector("td:contains(姓名)").First.Node.Next.InnerText

需要注意的是,Node之前的Next是在结果集中选择下一个对应的结果,Node之后的Next是在Html中对应的元素的下一个元素

好了,HtmlParser部分基本上讲完了,之后文盲老顾会尝试做一些数据提取方面新的尝试,在尽量减少指正的情况下,如何从页面内获取到我们想要的数据,例如自动解析表格之类的

这篇关于使用xpath实现document.querySelector样式选择器进行html解析(四):将选择结果封装进行输出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/746664

相关文章

使用Java将实体类转换为JSON并输出到控制台的完整过程

《使用Java将实体类转换为JSON并输出到控制台的完整过程》在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用JSON格式,用Java将实体类转换为J... 在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用j

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

Java实现图片淡入淡出效果

《Java实现图片淡入淡出效果》在现代图形用户界面和游戏开发中,**图片淡入淡出(FadeIn/Out)**是一种常见且实用的视觉过渡效果,它可以用于启动画面、场景切换、轮播图、提示框弹出等场景,通过... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细

Python实现获取带合并单元格的表格数据

《Python实现获取带合并单元格的表格数据》由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,所以本文我们就来聊聊如何使用Python实现获取带合并单元格的表格数据吧... 由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,现将将封装成类,并通过调用list_exc

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

Python logging模块使用示例详解

《Pythonlogging模块使用示例详解》Python的logging模块是一个灵活且强大的日志记录工具,广泛应用于应用程序的调试、运行监控和问题排查,下面给大家介绍Pythonlogging模... 目录一、为什么使用 logging 模块?二、核心组件三、日志级别四、基本使用步骤五、快速配置(bas

SQL 外键Foreign Key全解析

《SQL外键ForeignKey全解析》外键是数据库表中的一列(或一组列),用于​​建立两个表之间的关联关系​​,外键的值必须匹配另一个表的主键(PrimaryKey)或唯一约束(UniqueCo... 目录1. 什么是外键?​​ ​​​​2. 外键的语法​​​​3. 外键的约束行为​​​​4. 多列外键​

CSS3 布局样式及其应用举例

《CSS3布局样式及其应用举例》CSS3的布局特性为前端开发者提供了无限可能,无论是Flexbox的一维布局还是Grid的二维布局,它们都能够帮助开发者以更清晰、简洁的方式实现复杂的网页布局,本文给... 目录深入探讨 css3 布局样式及其应用引言一、CSS布局的历史与发展1.1 早期布局的局限性1.2

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs