惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Palo Alto Networks Blog
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
有赞技术团队
有赞技术团队
The GitHub Blog
The GitHub Blog
C
Cisco Blogs
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
Recent Announcements
Recent Announcements
Simon Willison's Weblog
Simon Willison's Weblog
T
Tenable Blog
Know Your Adversary
Know Your Adversary
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
月光博客
月光博客
Latest news
Latest news
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threat Research - Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
I
InfoQ
D
Darknet – Hacking Tools, Hacker News & Cyber Security
W
WeLiveSecurity
Hacker News - Newest:
Hacker News - Newest: "LLM"
酷 壳 – CoolShell
酷 壳 – CoolShell
U
Unit 42
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research
Attack and Defense Labs
Attack and Defense Labs
罗磊的独立博客
T
The Exploit Database - CXSecurity.com
I
Intezer
GbyAI
GbyAI
Jina AI
Jina AI
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Google Online Security Blog
Google Online Security Blog
Engineering at Meta
Engineering at Meta
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
小众软件
小众软件
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
Project Zero
Project Zero

博客园 - 网际飞狐

异步服务框架 如何在TFS中用命令行提交更新 CollabNet Subversion 输出自定义日期格式 - 网际飞狐 - 博客园 你正确关闭WCF链接了吗? 通过OperationContext添加消息头信息 PHP在II7安装指南 [Google App Engine] Hello, world! 在IIS7中配置使用Python 2008年12月小记(NewSequentialID(),ADO.NET Data Service,Visual Studio Tips,安装Django,JQuery智能感知) System.Web.Routing 使用基础 Notes for 2008-11(GetRange, backup,file hash, PostRequest, QueryString) JS通过服务代理调用跨域服务 对硬编码WCF服务的封装(提供服务和客户端调用的封装,调用样例....) Observer Pattern, Delegate and Event How to view the W3WP process by c#? 项目框架概要 2008年10月小记(SQL删除重复记录,生成表结构,字符串特性,statistics io) WinDbg使用摘要
[OpenAPI] html标签分析
网际飞狐 · 2008-11-25 · via 博客园 - 网际飞狐

     个人空间的OpenAPI与facebook非常接近(从需要求上就要做成一样),所以我们在hi中也将会使用类拟于fbml这样的自定义标签(himl)。在对notifications.send接口的开发中需要传入notification参数,这个参数是通知的内容,其实就是一些html和himl标签混合在一起的字符串,其中有一个需求:用户传进一个UserName参数要求我们把它变成这个用户的真实姓名,例如:<hi:name id="billok" />。这里就是一个himl自定义标签了。我们要做的工作就是要解析类拟的自定标签把它转换成真实姓名。

     框架还是有点复杂,为了表达清楚点,这里不谈很多细节,只列一下这个subject相关的内容。

     首先,应用程序把notification参数传入notifications.send接口后,会经过一点的流程把参数html传进如下一个处理请求的基类的方法:

string ParseContent(string html){}  这个方法是用户分析html参数把其中的himl标签进行特殊处理。

        protected virtual string ParseContent(string html)
        {
            
//加载html到HtmlDocument
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(HttpUtility.HtmlDecode(html));
//遍历第一层节点
            foreach (HtmlNode node in doc.DocumentNode.ChildNodes)
            {
                HtmlUtil.ForEach(node);
            }
return doc.DocumentNode.OuterHtml;
        }

这里我们使用了HtmlAgilityPack对html分析组件,首先把html字符串加裁成HtmlDocument对象,这样就会自动分析出文档的dom树结构,然后把我们通过遍历第一层节点,使用HtmlUtil.ForEach处理第一层根节点,处理完后就把所有的html进行输出。使用HtmlAgilityPack的好处是可以方便的对dom进行操作,可以删除节点和替换节点,不过相信还有更好的类库可以使用或者以后改为LINQ to xml进行处理。

     我们还是详细看一下ForEach方法的实现吧。

        public static void ForEach(HtmlNode node)
        {
            
if (node.NodeType != HtmlNodeType.Element)
            {
                
return;
            }
            
else
            {
                
if (!node.HasChildNodes)
                {
                    
//叶节点
                    HandleNode(node);
                }
                
else
                {
                    
foreach (HtmlNode childNode in node.ChildNodes)
                    {
                        ForEach(childNode);
                    }
                    
//子节点:有子与有父节点
                    HandleNode(node);
                }
            }
        }

这里实际上是一个递归操作,如果传进的节点不是一个Element元素(例如:不带标签的纯文件,注解等),这样的node我们是不需要处理的,所以就直接return终结循环就好了。对于Element节点的处理,就只分为有子节点和没有子节点的情况就行,如果有子节点的话就再遍历子节点并递归调用ForEach方法,目的就是把有Element处理一遍。你也发现了我们对节点的处理又被封装到另一个方法中了HandleNode:

        private static void HandleNode(HtmlNode node)
        {
            
//分析节点
            IHtmlTag iHtmlTag = ObjectFactory.CreateIHtmlTag(node.Name);
            Dictionary
<stringstring> dict = new Dictionary<stringstring>();
            //dict.Add("HtmlNode_OuterHtml", node.OuterHtml);//可以传入节点的全部html,以作进一步处理
            foreach (HtmlAttribute attr in node.Attributes)
            {
                
if (!dict.ContainsKey(attr.Name))
                {
                    dict.Add(attr.Name, attr.Value);
                }
            }
            HtmlTag htmlTag 
= iHtmlTag.Handle(dict);//处理节点
            switch (htmlTag.HandleType)
            {
                
case HtmlTagHandleType.Remove:
                    
if (node.ParentNode != null)
                        node.ParentNode.RemoveChild(node);
                    
break;
                
case HtmlTagHandleType.Replace:
                    
if (node.ParentNode != null)
                    {
                        HtmlNode newNode 
= HtmlNode.CreateNode(htmlTag.Html);
                        node.ParentNode.ReplaceChild(newNode, node);
                    }
                    
break;
                
case HtmlTagHandleType.Unknown:
                
default:
                    
//不做任务处理
                    break;

            }
        }

这个方法分为两个步聚:分析节点和处理节点,并且利用了IOC模式。

IOC模式是系统框架的一部分,这里就不详细谈了,你只要知道从ObjectFactory.CreateIHtmlTag方法可以得到标签名(如:hi:name)所以指定的关于IHtmlTag接口的一个实现,如果没有合符处理的实现就会使用一个默认实现(就是告诉"处理节点"步聚什么都不用做)。对于IHtmlTag接口我们看一下定义:

    public enum HtmlTagHandleType
    {
        Unknown,
        Remove,
        Replace,
    }
public class HtmlTag
    {
        
public HtmlTagHandleType HandleType { getset; }
        
public string Html { getset; }public HtmlTag()
        {
            HandleType 
= HtmlTagHandleType.Unknown;
            Html 
= string.Empty;
        }
    }
public interface IHtmlTag
    {
        HtmlTag Handle(IDictionary
<stringstring> attributes);
    }

IHtmlTag接口只有一个方法

HtmlTag Handle(IDictionary<string, string> attributes); 接受一个节点属性的键值对字典,返回对这些键值对进行处理的结果。

返回的HtmlTag可以指示出需要后续进行怎么样的操作(HtmlTagHandleType),以及处理完后的html

Okay! 对节点进行分析后得到HtmlTag,现在就可以进行节点处理的工作了。节点的处理方式以HtmlTagHandleType的返回为准,分别是Remove删除节点,Replace替换节点,不作处理。

经过这些处理后,返加doc.DocumentNode.OuterHtml就可以得到处理后的html内容了。通过实现IHtmlTag接口,可以很方便的添加新的himl标签对内容时行特殊处理了。并用标签还可以任竟扩展属性,例如:<hi:name id="billok,junbiaochen" target="abc" /> 等等。