亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#自寫的一個HTML解析類(類似XElement語法)

2020-01-24 01:46:42
字體:
來源:轉載
供稿:網友

功能:

1、輕松獲取指元素HTML元素。
2、可以根據屬性標簽進行篩選
3、返回的都是Llist強類型無需轉換

 
用過XElement的都知道 用來解析XML非常的方便,但是對于HTML的格式多樣化實在是沒辦法兼容。

所以我就寫了這么一個類似XElement的 XHTMLElement

用法:

string filePath = Server.MapPath("~/file/test.htm");      //獲取HTML代碼      string mailBody = FileHelper.FileToString(filePath);      XHtmlElement xh = new XHtmlElement(mailBody);      //獲取body的子集a標簽并且class="icon"      var link = xh.Descendants("body").ChildDescendants("a").Where(c => c.Attributes.Any(a => a.Key == "class" && a.Value == "icon")).ToList();      //獲取帶href的a元素      var links = xh.Descendants("a").Where(c => c.Attributes.Any(a => a.Key == "href")).ToList();      foreach (var r in links)      {        Response.Write(r.Attributes.Single(c => c.Key == "href").Value); //出輸href      }      //獲取第一個img      var img = xh.Descendants("img");      //獲取最近的第一個p元素以及與他同一級的其它p元素      var ps = xh.Descendants("p");

代碼:

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text;using System.Text.RegularExpressions;namespace SyntacticSugar{  /// <summary>  /// ** 描述:html解析類  /// ** 創始時間:2015-4-23  /// ** 修改時間:-  /// ** 作者:sunkaixuan  /// ** qq:610262374 歡迎交流,共同提高 ,命名語法等寫的不好的地方歡迎大家的給出寶貴建議  /// </summary>  public class XHtmlElement  {    private string _html;    public XHtmlElement(string html)    {      _html = html;    }    /// <summary>    /// 獲取最近的相同層級的HTML元素    /// </summary>    /// <param name="elementName">等于null為所有元素</param>    /// <returns></returns>    public List<HtmlInfo> Descendants(string elementName = null)    {      if (_html == null)      {        throw new ArgumentNullException("html不能這空!");      }      var allList = RootDescendants(_html);      var reval = allList.Where(c => elementName == null || c.TagName.ToLower() == elementName.ToLower()).ToList();      if (reval == null || reval.Count == 0)      {        reval = GetDescendantsSource(allList, elementName);      }      return reval;    }    /// <summary>    /// 獲取第一級元素    /// </summary>    /// <param name="elementName"></param>    /// <returns></returns>    public List<HtmlInfo> RootDescendants(string html = null)    {      /*       * 業務邏輯:             * 1、獲取第一個html標簽一直找結尾標簽,如果在這個過程中遇到相同的標簽收尾標簽就要加1             * 2、第一個標簽取到后繼續第一步操作,找第2個元素 。。第N個元素       */      if (html == null) html = _html;      var firstTag = Regex.Match(html, "<.+?>");      List<string> eleList = new List<string>();      List<HtmlInfo> reval = new List<HtmlInfo>();      GetElementsStringList(html, ref eleList);      foreach (var r in eleList)      {        HtmlInfo data = new HtmlInfo();        data.OldFullHtml = r;        data.SameLeveHtml = html;        data.TagName = Regex.Match(r, @"(?<=/s{1}|/<)[a-z,A-Z]+(?=/>|/s)", RegexOptions.IgnoreCase).Value;        data.InnerHtml = Regex.Match(r, @"(?<=/>).+(?=<)", RegexOptions.Singleline).Value;        var eleBegin = Regex.Match(r, "<.+?>").Value;        var attrList = Regex.Matches(eleBegin, @"[a-z,A-Z]+/="".+?""").Cast<Match>().Select(c => new { key = c.Value.Split('=').First(), value = c.Value.Split('=').Last().TrimEnd('"').TrimStart('"') }).ToList();        data.Attributes = new Dictionary<string, string>();        if (attrList != null && attrList.Count > 0)        {          foreach (var a in attrList)          {            data.Attributes.Add(a.key, a.value);          }        }        reval.Add(data);      }      return reval;    }    #region private    private List<HtmlInfo> GetDescendantsSource(List<HtmlInfo> allList, string elementName)    {      foreach (var r in allList)      {        if (r.InnerHtml == null || !r.InnerHtml.Contains("<")) continue;        var childList = RootDescendants(r.InnerHtml).Where(c => elementName == null || c.TagName.ToLower() == elementName.ToLower()).ToList();        if (childList == null || childList.Count == 0)        {          childList = GetDescendantsSource(RootDescendants(r.InnerHtml), elementName);          if (childList != null && childList.Count > 0)            return childList;        }        else        {          return childList;        }      }      return null;    }    private void GetElementsStringList(string html, ref List<string> eleList)    {      HtmlInfo info = new HtmlInfo();      info.TagName = Regex.Match(html, @"(?<=/</s{0,5}|/<)([a-z,A-Z]+|h/d{1})(?=/>|/s)", RegexOptions.IgnoreCase).Value;      string currentTagBeginReg = @"</s{0,10}" + info.TagName + @".*?>";//獲取當前標簽元素開始標簽正則      string currentTagEndReg = @"/<//" + info.TagName + @"/>";//獲取當前標簽元素收尾標簽正則      if (string.IsNullOrEmpty(info.TagName)) return;      string eleHtml = "";      //情況1 <a/>      //情況2 <a></a>      //情況3 <a> 錯誤格式      //情況4endif      if (Regex.IsMatch(html, @"</s{0,10}" + info.TagName + "[^<].*?/>"))//單標簽      {        eleHtml = Regex.Match(html, @"</s{0,10}" + info.TagName + "[^<].*?/>").Value;      }      else if (!Regex.IsMatch(html, currentTagEndReg))//沒有收尾      {        if (Regex.IsMatch(html, @"/s{0,10}/</!/-/-/[if"))        {          eleHtml = GetElementString(html, @"/s{0,10}/</!/-/-/[if", @"/[endif/]/-/-/>", 1);        }        else        {          eleHtml = Regex.Match(html, currentTagBeginReg,RegexOptions.Singleline).Value;        }      }      else      {        eleHtml = GetElementString(html, currentTagBeginReg, currentTagEndReg, 1);      }      try      {        eleList.Add(eleHtml);        html = html.Replace(eleHtml, "");        html = Regex.Replace(html, @"</!DOCTYPE.*?>", "");        if (!Regex.IsMatch(html, @"^/s*$"))        {          GetElementsStringList(html, ref eleList);        }      }      catch (Exception ex)      {        throw new Exception("SORRY,您的HTML格式不能解析?。?!");      }    }    private string GetElementString(string html, string currentTagBeginReg, string currentTagEndReg, int i)    {      string newHtml = GetRegNextByNum(html, currentTagBeginReg, currentTagEndReg, i);      var currentTagBeginMatches = Regex.Matches(newHtml, currentTagBeginReg, RegexOptions.Singleline).Cast<Match>().Select(c => c.Value).ToList();      var currentTagEndMatches = Regex.Matches(newHtml, currentTagEndReg).Cast<Match>().Select(c => c.Value).ToList();      if (currentTagBeginMatches.Count == currentTagEndMatches.Count)      { //兩個簽標元素相等        return newHtml;      }      return GetElementString(html, currentTagBeginReg, currentTagEndReg, ++i);    }    private string GetRegNextByNum(string val, string currentTagBeginReg, string currentTagEndReg, int i)    {      return Regex.Match(val, currentTagBeginReg + @"((.*?)" + currentTagEndReg + "){" + i + "}?", RegexOptions.IgnoreCase | RegexOptions.Singleline).Value;    }    #endregion  }  public static class XHtmlElementExtendsion  {    /// <summary>    /// 獲取最近的相同層級的HTML元素    /// </summary>    /// <param name="elementName">等于null為所有元素</param>    /// <returns></returns>    public static List<HtmlInfo> Descendants(this IEnumerable<HtmlInfo> htmlInfoList, string elementName = null)    {      var html = htmlInfoList.First().InnerHtml;      XHtmlElement xhe = new XHtmlElement(html);      return xhe.Descendants(elementName);    }    /// <summary>    /// 獲取下級元素    /// </summary>    /// <param name="elementName"></param>    /// <returns></returns>    public static List<HtmlInfo> ChildDescendants(this IEnumerable<HtmlInfo> htmlInfoList, string elementName = null)    {      var html = htmlInfoList.First().InnerHtml;      XHtmlElement xhe = new XHtmlElement(html);      return xhe.RootDescendants(html).Where(c => elementName == null || c.TagName == elementName).ToList();    }    /// <summary>    /// 獲取父級    /// </summary>    /// <param name="htmlInfoList"></param>    /// <returns></returns>    public static List<HtmlInfo> ParentDescendant(this IEnumerable<HtmlInfo> htmlInfoList,string fullHtml)    {      var saveLeveHtml = htmlInfoList.First().SameLeveHtml;      string replaceGuid=Guid.NewGuid().ToString();      fullHtml = fullHtml.Replace(saveLeveHtml,replaceGuid);      var parentHtml = Regex.Match(fullHtml, @"<[^<]+?>[^<]*?" + replaceGuid + @".*?<//.+?>").Value;      parentHtml = parentHtml.Replace(replaceGuid, saveLeveHtml);      XHtmlElement xhe = new XHtmlElement(parentHtml);      return xhe.RootDescendants();    }  }  /// <summary>  /// html信息類  /// </summary>  public class HtmlInfo  {    /// <summary>    /// 元素名    /// </summary>    public string TagName { get; set; }    /// <summary>    /// 元素屬性    /// </summary>    public Dictionary<string, string> Attributes { get; set; }    /// <summary>    /// 元素內部html    /// </summary>    public string InnerHtml { get; set; }    public string OldFullHtml { get; set; }    public string SameLeveHtml { get; set; }    /// <summary>    /// 得到元素的html    /// </summary>    /// <returns></returns>    public string FullHtml    {      get      {        StringBuilder reval = new StringBuilder();        string attributesString = string.Empty;        if (Attributes != null && Attributes.Count > 0)        {          attributesString = string.Join(" ", Attributes.Select(c => string.Format("{0}=/"{1}/"", c.Key, c.Value)));        }        reval.AppendFormat("<{0} {2}>{1}</{0}>", TagName, InnerHtml, attributesString);        return reval.ToString();      }    }  }}

前臺HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head>  <title></title></head><body>  <a id="1">我是1</a>   <a id="2" class="icon">icon</a>  <img /></body></html>

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产日韩欧美夫妻视频在线观看| 欧美日韩亚洲精品内裤| 国产91色在线免费| 亚洲人成啪啪网站| 亚洲成人黄色在线观看| 91精品国产综合久久久久久久久| 国产欧美精品一区二区| 欧美亚洲国产日韩2020| 国产成人精品免费久久久久| 国产女同一区二区| 国产欧美一区二区三区久久人妖| 国产精品免费久久久久久| 亚洲国产97在线精品一区| 日本精品视频在线观看| 一区二区三区高清国产| 91爱视频在线| 亚洲美女自拍视频| 久久精品国产电影| 成人在线免费观看视视频| 成人免费午夜电影| 欧美大尺度电影在线观看| 91亚洲国产成人久久精品网站| 综合网中文字幕| 日韩黄色av网站| 一区二区三区动漫| 精品免费在线视频| 亚洲aaaaaa| 欧美亚洲国产日韩2020| 日韩免费av片在线观看| 欧美放荡办公室videos4k| 久久久999成人| 三级精品视频久久久久| 久久久国产视频| 欧美激情在线播放| 欧美天天综合色影久久精品| 日韩中文字幕视频在线观看| 欧美刺激性大交免费视频| 久久久人成影片一区二区三区观看| 亚洲免费视频一区二区| 理论片在线不卡免费观看| 欧美成人剧情片在线观看| 国产婷婷色综合av蜜臀av| 国产精品扒开腿做爽爽爽视频| 日韩免费高清在线观看| 久久频这里精品99香蕉| 日本伊人精品一区二区三区介绍| 成人h片在线播放免费网站| 成人在线国产精品| 亚洲精品动漫久久久久| 亚洲男人天堂视频| 2019精品视频| 精品国产欧美一区二区三区成人| 国产91成人video| 日韩精品在线免费观看视频| 日韩av在线免费观看| 欧美性69xxxx肥| 亚洲人成网站999久久久综合| 亚洲欧美激情另类校园| 国产精品夫妻激情| 国产精品福利在线观看| 久久久久久久久久久av| 日韩av一卡二卡| 日韩中文字幕在线精品| 欧美成人黑人xx视频免费观看| 亚洲美女av黄| 国产精品www网站| 69av视频在线播放| 欧美在线视频导航| 成人信息集中地欧美| 午夜精品久久17c| 欧美日韩在线观看视频| 成人精品一区二区三区电影黑人| 亚洲福利影片在线| 欧美一级成年大片在线观看| 亚洲精品影视在线观看| 国产精品video| 国产精品自产拍在线观| 日韩在线观看av| 欧美午夜片欧美片在线观看| 亚洲第一中文字幕| 在线精品91av| 国产剧情日韩欧美| 中文字幕久热精品在线视频| 亚洲精品理论电影| 亚洲电影av在线| 亚洲91精品在线观看| 91九色单男在线观看| 久久久之久亚州精品露出| 亚洲美腿欧美激情另类| 亚洲国产欧美在线成人app| 欧美成人性色生活仑片| 久久久免费电影| 久久久亚洲国产| 国产99视频在线观看| 九九久久久久久久久激情| 欧美性猛交视频| 欧美性猛交xxxx乱大交蜜桃| 韩国日本不卡在线| 亚洲视频999| 日韩av在线天堂网| 亚洲免费高清视频| 国产丝袜一区二区三区免费视频| 92版电视剧仙鹤神针在线观看| 亚洲成人免费网站| 中文字幕日韩精品有码视频| 欧美在线视频一二三| 欧美色道久久88综合亚洲精品| 日韩一区二区av| 久久久欧美精品| 精品美女国产在线| 亚洲视频在线观看视频| 北条麻妃99精品青青久久| 欧美精品免费在线| 日本一区二区不卡| 最近更新的2019中文字幕| 欧美国产日韩中文字幕在线| 4438全国成人免费| 91av在线不卡| 色噜噜国产精品视频一区二区| 亚洲激情视频在线观看| 精品亚洲一区二区| 久久久久久久久久久成人| 91精品国产综合久久香蕉922| 欧美黑人极品猛少妇色xxxxx| 亚洲精品成人久久久| 国产噜噜噜噜噜久久久久久久久| 情事1991在线| 国产香蕉一区二区三区在线视频| 亚洲视屏在线播放| 亚洲精品国产免费| 97国产真实伦对白精彩视频8| 国产精品成人久久久久| 中文字幕日韩高清| 久久久国产91| 91精品久久久久久久久久入口| 国产成人亚洲综合91| 国产精品久久久久久亚洲调教| 成人精品在线观看| 久久国产精品久久久久| 欧美视频在线看| 国产欧美一区二区三区久久人妖| 久久亚洲精品网站| 成人精品一区二区三区| 国产精品免费久久久久久| 成人免费激情视频| 亚洲成人动漫在线播放| 成人妇女免费播放久久久| 91精品国产乱码久久久久久久久| 亚洲女人被黑人巨大进入| 国产精品偷伦免费视频观看的| 欧美美女操人视频| 久久久99免费视频| 91美女片黄在线观看游戏| 久久夜色精品国产欧美乱| 久久精品国产一区二区电影| 精品国产欧美一区二区三区成人| 国产精品91久久久| 欧美另类交人妖| 亚洲最大的av网站| 日韩亚洲在线观看| 91精品国产91久久久久久久久| 亚洲人成网站999久久久综合| 成人av在线网址| 欧美高清第一页|