//html 简单解析器 import string.xml; namespace string; class html{ ctor( str ){ this = ..string.xml(str,xmlElementType,optionalTags) }; } namespace html; //可选标签,用于处理可以省略闭合标签的元素 optionalTags = { body={head=1};// body 元素开始标签可自动关闭上一个省略结束标签的 head 节点 li={li=1};//li 元素开始标签可自动关闭上一个省略结束标签的 li 节点 dt={dt=1;dd=1}; dd={dt=1;dd=1}; rt={rt=1;rp=1}; rp={rt=1;rp=1}; optgroup={optgroup=1;option=1}; option={option=1}; tbody={thead=1;tbody=1;th=1;tr=1;td=1;caption=1;colgroup=1;col=1}; tfoot={thead=1;tbody=1;tr=1;th=1;td=1;caption=1;colgroup=1;col=1}; thead={caption=1;colgroup=1;caption=1;col=1}; colgroup={colgroup=1;col=1;caption=1;}; tr={tr=1;td=1;th=1;caption=1;colgroup=1;col=1}; td={td=1;th=1}; th={td=1;th=1}; address={p=1}; article={p=1}; aside={p=1}; blockquote={p=1}; details={p=1}; div={p=1}; dl={p=1}; fieldset={p=1}; figcaption={p=1}; figure={p=1}; footer={p=1}; form={p=1}; h1={p=1}; h2={p=1}; h3={p=1}; h4={p=1}; h5={p=1}; h6={p=1}; header={p=1}; hr={p=1}; main={p=1}; nav={p=1}; ol={p=1}; p={p=1}; pre={p=1}; section={p=1}; table={p=1}; ul={p=1}; } xmlElementType = { //1 Void elements area=1;base=1;br=1;col=1;embed=1;hr=1;img=1;input=1;link=1;meta=1;param=1;source=1;track=1;wbr=1; //2 Raw text elements script=2;style=2;textarea=2;title=2; } var rep = ..string.replace; removeTag = function(html,tag,...){ var html = rep(html,"\<\!--.*?--\>" , ""); html = rep(html, "\<\s*<@@"+tag+"@>[^\>]*?\s*\>.*?\<\s*/<@@"+tag+"@>\s*>",""); html = rep(html, "\<\s*<@@"+tag+"@>!\W[^\>]*?\s*\>.+?\<\s*/","!\W[^\>]*?\s*\>.+",""); if(!...) return html; return removeTag(html,...); } toXml = function(html){ var doc = ..string.html(html); if(!doc) return; var dt = doc.queryEle(tagName="!doctype") if(dt) dt.remove(); var root = doc.queryEle(tagName="html") if(!root){ doc.tagName = ( doc.queryEle(tagName="body") || doc.queryEle(tagName="head") ) ? "html" : "body"; root = doc; } return `` + root.outerXml(); } toText = function(html){ if(!html) return; var html = rep(html,"\<\!--.*?--\>" , ""); html = ..string.match(html,"\<\s*<@@body@>[^\>]*?\s*\>.+") : html; html = removeTag(html,"head","style","script"); html = rep(html, "\<\s*pre[^\>]*?\s*\>(.*?)\<\s*/pre\s*>", function(c){ c = rep(c," "," "); c = rep(c,'\n',"
"); return c; } ); html = rep(html,"\s+"," "); html = rep(html,"\<[bB][rR]\s*/*\>",'\r\n'); html = rep(html,"\",'\r\n'); html = rep(html,"\",'\r\n'); html = rep(html,"\",'\r\n'); html = rep(html,"\<.+?\>",""); return ncr(html); } fromText = function(v){ if(!v) return; v = rep(v,"@&",'&'); v = rep(v,'@<',"<"); v = rep(v,'@>',">"); v = rep(v,'@"',"""); v = rep(v,"@'","'"); v = rep(v," "," "); v = rep(v,'\r\n',"
"); v = rep(v,'\n',"
"); v = rep(v,'\r',"
"); return v; } escape = ..string.xml.escape; ncrDecode = ..string.xml.ncrDecode; ncrEncode = ..string.xml.ncrEncode; ncr = ..string.xml.ncr;//@Deprecated /**intellisense() string.html = HTML 简单解析器。\n\n严格的校验 HTML 语法正确性不是本模块的设计目标,\n所以此解析器尽可能兼容错误,兼容了 HTML,SGML 的部分规则:\n1. 不要求存在根标签 \n2. 尝试自动修正不配对的标记 \n3. 在有必要的时候尝试忽略大小写\n4. 支持识别 HTML 空标签、省略闭合标签规则 string.html(__) = 创建HTML解析器,参数请指定包含HTML代码的字符串,\n调用string.xml解析HTML代码,用法与string.xml相同\n但支持识别HTML空标签、省略闭合标签规则\n\n此对象不支持 table.tostring , console.dump 函数,不能跨线程传递 string.html() = !string_xml. string.html.escape(__) = 将字符串中的 < > " ' & 等 HTML 标记字符编码为实体字符(entity)。\n如果参数为非 null 值则返回转换后的字符串。\n参数只能是 null 或字符串、buffer string.html.ncrEncode(.(str,pattern) = 将字符串参数 @str 中以 @pattern 指定模式串所匹配的字符进行 NCR 编码。\n参数 @pattern 可用模式匹配语法指定要编码的字符,省略则默认为 ":|."。\n返回编码后的字符串。 string.html.ncrDecode(__) = NCR 编码字符、HTML 实体字符还原为 UTF8 文本 string.html.toText(__/*HTML代码*/) = 将HTML代码转换为文本 string.html.fromText(__/*普通文本*/) = 将普通文本转换为HTML string.html.removeTag(html,"script__") = 移除指定的html标记,支持不定个数的标记参数 string.html.toXml(__/*HTML代码*/) = 将 HTML 代码转换为 XML 文本 end intellisense**/ /**details(使用说明) string.html 继承自 string.xml ,基本用法与 string.xml 相同。 string.html 每个 HTML 节点对象都是一个表对象(table), 这些 HTML 节点对象如果有 tagName 属性表示标记名 - 那他就是一个普通节点。 如果没有 tagName 属性而是拥有 text 或 cdata属性 - 那就说明它是一个 text 文本节点或者是 cdata 节点。 string.html 提供以下四种类型的节点: 1. 拥有标签名( tagName 属性)的普通 HTML 元素 普通 HTML 节点使用 tagName 属性表示 XML 标记名, 在 string.html 中 "tagName"属于保留的 HTML 属性,其他属性使用此属性名将会被自动忽略。 > XML 声明节点的 tagName 为"?xml" 2. 顶层根节点 string.html 总是虚拟出一个空的没有 tagName 属性的顶层根节点, 这个根节点是文档里的 XML/HTML 真实根节点的父节点。 3. 文本节点 文本节点使用 text 属性表示文本,无 tagName 属性,无其他属性。 4. CDATA节点 CDATA 节点使用 cdata 属性表示数据, 无 tagName 属性,无其他属性 注释节点被自动忽略不会存为节点对象。 end details**/