实现html转Xml
2023-09-11 14:17:10 时间
最近在做一些网页信息采集的工作,说通俗点就是爬虫工具,要监控页面中某一部分内容是否发生变化。起初考虑用正则表达式去匹配网页源码,经过咨询有经验人士,推荐使用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
}
相关文章
- java解析XML saxReader.read(xml) 错误:org.dom4j.DocumentException: no protocol
- HTML Tags containing Vue.js v-if and v-for directives flash at loading
- python Excel数据表格转为HTML网页数据表格
- 优化 html 标签 为何能用HTML/CSS解决的问题就不要使用JS?
- Word控件Spire.Doc 转换教程(十四):使如何在 C#、VB.NET 中将 HTML 转换为 XML
- Word处理控件Aspose.Words功能演示:使用 Java 将 Word 文档 (DOC/DOCX) 转换为 HTML
- 手机微信中也能播放mp3音乐的方法(测试通过的html源代码)
- XML解析之SAX方式解析xml文件
- c#中使用XSLT将xml文档转换为html文档方法
- C# XML 添加,修改,删除Xml节点
- 动态创建html元素的几种方法
- Day8:html和css
- 【用ddt思想重构项目】Selenium读取XML文件:基于unittest框架,借助ddt模块,使用xml文件作为测试输入
- 一款很不错的html转xml工具-Html Agility Pack
- vue项目index.html缓存
- 《重构HTML:改善Web应用的设计(修订版)》——2.2 验证器
- 【XML和Java】手写Java程序引用xsd验证xml
- JMeter学习-039-JMeter 3.0 生成 dashboard HTML 报告图表中文乱码
- 安装eclipse中html/jsp/xml editor插件以及改动html页面的字体
- Web 之 html 如何显示隐藏Html元素的两种方法简单整理
- CYQ.Data.Xml XmlHelper 助你更方便快捷的操作Xml/Html
- 【xml】XML技术
- XML和HTML中的转义字符