前言:
这两天在对 Taurus.Mvc做 html加载性能优化时,发现存在这个问题。
具体优化的是 CYQ.Data组件的 XHtmlAction相关类。
问题过程:
之前 XmlDocument调用LoadXml(xml)之后,缓存对象,再次使用时,都是重新LoadXml:
XmlDocument newDoc = new XmlDocument(); try { newDoc.LoadXml(缓存xDoc.InnerXml); } catch (Exception err) { Log.Write(err, LogType.Error); newDoc.InnerXml = xDoc.InnerXml; } return newDoc;
上面的代码,多年来一直工作很好,直到最近,在做优化,发现还原节点,可以通过 Clone 方式,而且性能提升不少:
代码如:
//克隆速度快。 return 缓存xDoc.Clone() as XmlDocument;
后面发现用 CloneNode方式,还能更优一点:
//克隆速度快。 return 缓存xDoc.CloneNode(true) as XmlDocument;
以为问题解决时,却出现了样式怪异的问题,一开始以为是克隆还保持引用的问题,花了不少时间,找错了方向。
经反复排查,对比生成的内容,才发现以上的方法,都会造成 div空节点标签被自闭合了:
成了:
经测试,确认是该问题(仅.NET版本出问题,.NET Core在以上方法,不会产生自闭合问题)。
解决问题:
要解决这个问题,网上找找解决方案:
意外发现还有 ImportNode方式可以用,尝试了一下,似乎更优一丁点,蚊子腿也是肉:
HtmlDocument document = new HtmlDocument();
XmlNode node = document.ImportNode(缓存xDoc.DocumentElement, true);
document.AppendChild(node);
return document;
但,网上只有个别提问题,没有解决方案。
但发现了标签是否闭合和以下属性有关:
设置 XmlElement 的 IsEmpty = false;//不自闭合标签
而Clone或 ImportNode,没有提供参数设置该参数。
没思路的时候,就多看看.Net源码。
于是,想到通过继承:XmlDocument,改写 CreateElement 方法,来实现:
class XHtmlDocument : XmlDocument { public override XmlElement CreateElement(string prefix, string localName, string namespaceURI) { XmlElement xe = base.CreateElement(prefix, localName, namespaceURI); switch (localName) { case "meta": case "br": case "hr": c服务器托管网ase "img": case "link": case "base": case "area": case "input": case "source": case "!DOCTYPE": break; default: xe.IsEmpty = false;//不自闭合标签 break; } return xe; } }
总结:
Xml 需要标签不自闭合的场景,可能很少,但若需要,这就是个解决方案之一。
再补充 CYQ.Data关于加载 html的性能优化说明:
/* * 性能优化说明: * 1、DTD:如果界面没有实体&xxx;则不加载,否则修改DTD路径到本地。 * 2、XmlDocument:LoadXml 性能优化:加载后缓存,后续从缓存转化:这里要转化也没那么简单,需要解决以下问题: * --------------------------------------------------------------------------------------- * A、从缓存拿到,从缓存Doc拿出InnerXml,再重新LoadXml(xml),兼容性最好,但可优化。 * B、从缓存拿到,从缓存Doc调用:Clo服务器托管网ne、CloneNode(true)、两个性能差不多,节点多时,后面那个更优。 * C、从缓存拿到,从缓存Doc发现:XmlDocument ImportNode 方法比CloneNode(true) 更优,准备采用这个。 * D、上面B、C两种方式,产生新的问题:.NET 下标签自闭合、.NET Core下正常,改动见:GetCloneFrom 方法。 * E、解决标签自闭合问题:继承XmlDocument,改写CreateElement,根据W3C标准找出需要自闭合的,其余条件设置XmlElement的IsEmpty=false,见:XhtmlDocument * F、解决上述问题后,为了性能,从缓存中不加载DTD、引发样式问题: * G、解决F的问题是,输出的时候检测没有DTD头,则追加:头,见:XHtmlAction OutXml输出。 * ---------------------------------------------------------------------------------------- * 4、避免使用 InnerXml 属性,用其它方式替代:InnerText、节点引用等,但引发另一个问题,赋值text,则后续无法通过节点操作,这在循环绑定时会拿不到节点。 */
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 高效处理异常值的算法:One-class SVM模型的自动化方案
一、引言 数据清洗和异常值处理在数据分析和机器学习任务中扮演着关键的角色。清洗数据可以提高数据质量,消除噪声和错误,从而确保后续分析和建模的准确性和可靠性。而异常值则可能对数据分析结果产生严重影响,导致误导性的结论和决策。因此,有效的异常值处理方法对于保证数据…