我需要一种方法将数字HTML实体转换为等效的纯文本字符。例如,我想转变实体:
é
进入角色:
é
通过一些谷歌搜索我发现了一个名为HtmlUnEditFormat的函数,但这个函数只转换命名实体。有没有办法在ColdFusion中解码数字实体?
答案 0 :(得分:28)
感谢Todd Sharp指出一个非常简单的方法,使用Apache Commons StringEscapeUtils库,它与CF(和Railo)一起打包,所以你可以这样做:
<cfset Entity = "&##0233;" />
<cfset StrEscUtils = createObject("java", "org.apache.commons.lang.StringEscapeUtils") />
<cfset Character = StrEscUtils.unescapeHTML(Entity) />
那个链接的函数是icky - 没有必要明确地命名它们,正如你所说它没有做数字。
更简单的是让CF为您完成工作 - 使用XmlParse
函数:
<cffunction name="decodeHtmlEntity" returntype="String" output="false">
<cfargument name="Entity" type="String" hint="&##<number>; or &<name>;" />
<cfreturn XmlParse('<xml>#Arguments.Entity#</xml>').XmlRoot.XmlText />
</cffunction>
那个可以和Railo一起使用的,我不记得CF是否支持这种语法,所以你可能需要把它改成:
<cffunction name="decodeHtmlEntity" returntype="String" output="false">
<cfargument name="Entity" type="String" hint="&##<number>; or &<name>;" />
<cfset var XmlDoc = XmlParse('<xml>#Arguments.Entity#</xml>') />
<cfreturn XmlDoc.XmlRoot.XmlText />
</cffunction>
答案 1 :(得分:3)
这是另一个解码字符串中所有数字html字符实体的函数。它不依赖于xml解析,因此它将适用于包含不平衡xml标记的字符串。如果字符串具有大量实体,则效率不高,但如果没有/很少,则效果非常好。我只在Railo上测试了这个,而不是AdobeCF。
<cffunction name="decodeHtmlEntities" returntype="String" output="false">
<cfargument name="s" type="String"/>
<cfset var LOCAL = {f = ReFind("&##([0-9]+);", ARGUMENTS.s, 1, true), map={}}>
<cfloop condition="LOCAL.f.pos[1] GT 0">
<cfset LOCAL.map[mid(ARGUMENTS.s, LOCAL.f.pos[1], LOCAL.f.len[1])] = chr(mid(ARGUMENTS.s, LOCAL.f.pos[2], LOCAL.f.len[2]))>
<cfset LOCAL.f = ReFind("&##([0-9]+);", ARGUMENTS.s, LOCAL.f.pos[1]+LOCAL.f.len[1], true)>
</cfloop>
<cfloop collection=#LOCAL.map# item="LOCAL.key">
<cfset ARGUMENTS.s = Replace(ARGUMENTS.s, LOCAL.key, LOCAL.map[LOCAL.key], "all")>
</cfloop>
<cfreturn ARGUMENTS.s />
</cffunction>
答案 2 :(得分:1)
自己编写代码应该很容易。只需编辑您找到的HtmlUNEditFormat()函数,将它们包含在lEntities&amp;的末尾。 lEntitiesChars。
答案 3 :(得分:0)
我在使用一种方法时发现了这个问题,该方法通过黑盒原则,不能相信传入的字符串是HTML实体编码的,也可能不是。
我已经改编了Peter Boughton的功能,以便可以安全地使用尚未使用HTML实体处理过的字符串。 (唯一一次这似乎很重要的是当松散的&符号 - 即“Cats&amp; Dogs” - 出现在目标字符串中时。)这个修改后的版本在任何不可预见的XML解析错误上也会有些优雅地失败。
<cffunction name="decodeHtmlEntity" returntype="string" output="false">
<cfargument name="str" type="string" hint="&##<number>; or &<name>;" />
<cfset var XML = '<xml>#arguments.str#</xml>' />
<cfset var XMLDoc = '' />
<!--- ampersands that aren't pre-encoded as entities cause errors --->
<cfset XML = REReplace(XML, '&(?!(\##\d{1,3}|\w+);)', '&', 'all') />
<cftry>
<cfset XMLDoc = XmlParse(XML) />
<cfreturn XMLDoc.XMLRoot.XMLText />
<cfcatch>
<cfreturn arguments.str />
</cfcatch>
</cftry>
</cffunction>
这将安全地支持以下用例:
<cffunction name="notifySomeoneWhoCares" access="private" returntype="void">
<cfargument name="str" type="string" required="true"
hint="String of unknown preprocessing" />
<cfmail from="process@domain.com" to="someoneWhoCares@domain.com"
subject="Comments from Web User" format="html">
Some Web User Spoke Thus:<br />
<cfoutput>#HTMLEditFormat(decodeHTMLEntity(arguments.str))#</cfoutput>
</cfmail>
</cffunction>
此功能现在非常有用,可确保Web提交的内容在通过电子邮件发送或提交到数据库表之前是实体安全的(想想XSS)。
希望这有帮助。