实现html转Xml
最近在做一些网页信息采集的工作,说通俗点就是爬虫工具,要监控页面中某一部分内容是否发生变化。起初考虑用正则表达式去匹配网页源码,经过咨询有经验人士,推荐使用xpath去获取页面内容能获得更好的效率。但是对于html这种宽松语法要求的语言来说,不可能100%地完全符合xml标准,那么就没法使用xpath,说得更直接点就是:不能把html源码直接加载到xmldocument中。为了使用xpath,只能对html内容进行转换或者规范,于是就写了这么一个方法。
该方法比较地偷懒,借助了开源工具htmlparser获取html源码中的所有节点,然后遍历各个节点,转换为对应的xmlnode。对于html中有未闭合的节点,在转换后实际代码会有一些差别,但是不影响xpath的使用(这也跟如何写xpath的内容有关)。
实现方式如下,需引用htmlparser的dll
/// <summary>
/// 解析Xml文件的帮助类
/// </summary>
public class XMLHelper
{
/// <summary>
/// 有效名称的正则表达式
/// </summary>
static string validName = @"^[^\$\/;""\!#\)\.]+$"; #region CovertHtmlToXml
/// <summary>
/// 转换html源码为xml格式
/// </summary>
/// <param name="html">html源码</param>
/// <returns>xml字符串</returns>
/// <param name="TargetTag">需转换的标记名</param>
public static string CovertHtmlToXml(string html, string targetTag)
{
try
{
XmlDocument doc = new XmlDocument();
XmlNode xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
doc.AppendChild(xmlDeclaration); // 借助htmlparser解析html内容
Parser parser = Parser.CreateParser(html, "GBK");
// 筛选出指定的节点
TagNameFilter tnf = new TagNameFilter(targetTag);
NodeList nodes = parser.Parse(tnf); // 创建根节点
XmlElement root = doc.CreateElement("Tags"); TagNode tagNode = null;
Hashtable ht = null;
XmlAttribute attr = null;
XmlElement parent = null;
for (int i = 0; i < nodes.Size(); i++)
{
tagNode = nodes[i] as TagNode;
parent = doc.CreateElement(tagNode.TagName);
// 添加属性
ht = tagNode.Attributes;
foreach (DictionaryEntry ent in ht)
{
// 查看属性名是否合法
if (Regex.IsMatch(ent.Key.ToString(), validName))
{
attr = doc.CreateAttribute(ent.Key.ToString());
attr.Value = ent.Value.ToString();
parent.Attributes.Append(attr);
}
}// end foreach (DictionaryEntry ent in ht) AppendChild(tagNode, parent, doc); root.AppendChild(parent);
}
doc.AppendChild(root); return doc.OuterXml; //throw new Exception("给定的html文本必须至少包含一个" + targetTag + "节点");
}
catch (Exception ex)
{
throw new Exception("转换html内容出错:" + ex.Message);
}
} /// <summary>
/// 添加子节点
/// </summary>
/// <param name="tagNode">Html的父节点</param>
/// <param name="parent">Xml的父节点</param>
/// <param name="doc">Xml文档对象</param>
private static void AppendChild(INode tagNode, XmlNode parent, XmlDocument doc)
{
INode node = null;
XmlNode xmlNode = null;
XmlAttribute attr = null;
Hashtable ht = null; // 判断是否包含子节点
if (tagNode.Children != null && tagNode.Children.Size() > 0)
{
for (int i = 0; i < tagNode.Children.Size(); i++)
{
node = tagNode.Children[i];
xmlNode = null;
attr = null;
ht = null; // 如果是html标记节点
if (node is TagNode)
{
TagNode tn = node as TagNode;
if (Regex.IsMatch(tn.TagName, validName))
{
xmlNode = doc.CreateElement(tn.TagName); // 添加属性
ht = tn.Attributes;
foreach (DictionaryEntry ent in ht)
{
// 查看属性名是否合法
if (Regex.IsMatch(ent.Key.ToString(), validName))
{
attr = doc.CreateAttribute(ent.Key.ToString());
attr.Value = ent.Value.ToString();
xmlNode.Attributes.Append(attr);
}
}
}
} // 如果是文本节点
if (node is TextNode)
{
xmlNode = doc.CreateTextNode((node as TextNode).ToPlainTextString());
} if (xmlNode != null)
{
parent.AppendChild(xmlNode);
AppendChild(node, xmlNode, doc);
}
}
}
}
#endregion
}
实现html转Xml的更多相关文章
- XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法
在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...
- .NET Core采用的全新配置系统[9]: 为什么针对XML的支持不够好?如何改进?
物理文件是我们最常用到的原始配置的载体,最佳的配置文件格式主要由三种,它们分别是JSON.XML和INI,对应的配置源类型分别是JsonConfigurationSource.XmlConfigura ...
- WebApi接口 - 响应输出xml和json
格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况:希望大家喜欢,也希望各位多多扫码支持和点 ...
- XML技术之DOM4J解析器
由于DOM技术的解析,存在很多缺陷,比如内存溢出,解析速度慢等问题,所以就出现了DOM4J解析技术,DOM4J技术的出现大大改进了DOM解析技术的缺陷. 使用DOM4J技术解析XML文件的步骤? pu ...
- UWP开发之Mvvmlight实践六:MissingMetadataException解决办法(.Net Native下Default.rd.xml配置问题)
最近完成一款UWP应用,在手机端测试发布版(Release)的时候应用莫名奇妙的强行关闭,而同样的应用包在PC端一点问题都没有,而且Debug版在两个平台都没有问题,唯独手机的Release版有问题. ...
- PHP中遍历XML之SimpleXML
简单来讲述一些XML吧,XML是可扩展标记语言,是一种用于标记电子文件使其具有结构性的标记语言.XML是当今用于传输数据的两大工具之一,另外一个是json. 我们在PHP中使用XML也是用来传输数据, ...
- Asp.Net 操作XML文件的增删改查 利用GridView
不废话,直接上如何利用Asp.NET操作XML文件,并对其属性进行修改,刚开始的时候,是打算使用JS来控制生成XML文件的,但是最后却是无法创建文件,读取文件则没有使用了 index.aspx 文件 ...
- Mybatis XML配置
Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素”
Q: 在反序列化 Xml 字符串为 Xml 对象时,抛出如下异常. 即在 XML文档(0, 0)中有一个错误:缺少根元素. A: 首先看下代码: StringBuilder sb = new Stri ...
随机推荐
- 滑动开关效果 css3滑动开关】纯CSS3代码实现滑动开关效果-css3滑动效果-css3左右滑动
今天看到一篇有关 css3事件的博文,一时兴起便整理下相关的资料. 点击按钮,可以实现开关的滑动效果. 今天看到一篇有关 css3事件的博文,一时兴起便整理下相关的资料. 点击按钮,可以实现开关的滑动 ...
- mysql 中执行的 sql 注意字段之间的反向引号和单引号
如下的数据表 create table `test`( `id` int(11) not null auto_increment primary key, `user` varchar(100) no ...
- ubuntu使用github
Ubuntu下安装Git Ubuntu12.04 LTS默认是已经安装Git的,可以使用 git --version 测试是否安装.如果没有安装,使用命令: sudo apt-get install ...
- C 字符串倒转,XCode中编译
正在学习ios开发,在前期学习c时,常规方法直接倒转数组的值,只能用于非中文字符,否则出现乱码, 在网上找了点资料,可能是 IDE不一致,一直得不到自己想要的值.花时间自己改了一下,正常通过 //字符 ...
- 检测目标程序ELF bit是32还是64
android操作系统在5.0之后加入了对64位程序的支持,同时兼容运行32位的进程 android的进程绝大部分是zygote父进程fork出来的子进程 zygote进程fork出来的进程是32位进 ...
- 配置安装theano环境(非GPU版)
终于成功配置了theano环境,但由于本机没有gpu,所以配置的是非gpu版本的theano,下面将具体过程进行描述(安装成功后,有时对python的各种库进行更新时,可能会导致某个模块无法调用其他被 ...
- bzoj 1257: [CQOI2007]余数之和sum 数学 && 枚举
1257: [CQOI2007]余数之和sum Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 1779 Solved: 823[Submit][Sta ...
- 【JavsScript】XMLHttpRequest2的进步之处
本文参考自:XMLHttpRequest2 新技巧 (重点保留demo,方便自己日后查阅) HTML5是现在web开发中的热点,虽然关于web app和local app一直有争论,但是从技术学习的角 ...
- 【HDU3440】House Man (差分约束)
题目: Description In Fuzhou, there is a crazy super man. He can’t fly, but he could jump from housetop ...
- php生成二维码,使用qrcode类库创建
传说Google有个接口,可以生成二维码,这让我有点鸡冻不已,于是,......(省略1000字).结果,我找到了另外一个方法,是使用一个php类库,该工具叫:qrcode,但下载该工具可真是要人命. ...