简体   繁体   中英

How can I escape HTML character entities when using ColdFusion function XMLFormat()?

I have the following block of HTML:

<p>The quick brown fox jumps over the lazy dog &mdash; The quick brown fox jumps over the lazy dog.</p>
<p>The quick brown fox jumps over the lazy dog &mdash; The quick brown fox jumps over the lazy dog.
<br>The quick brown fox jumps over the lazy dog &mdash; The quick brown fox jumps over the lazy dog.

It is NOT valid XHTML. However, I need to include this HTML in an XML document. I tried using XMLFormat() in order to convert the < to &lt; and the > to &gt; , which works great. Unfortunately, it also converts &mdash; to &amp;mdash; , which is not valid and throws an exception in the CFXML tag.

<cfxml variable="myXML">
    <content>#XMLFormat(myHTML)#</content>
</cfxml>

How can I workaround this?

You have a few options. A lot depends on how this content is going to be used. It would be extremely helpful to include a desired output document, as well as indicate where this xml is being used.

If you don't want to mess with the content of the HTML at all, you could always use CDATA , like this:

<cfxml variable="myXML">
    <content><![CDATA[#myHTML#]]></content>
</cfxml>

Also, I know you say you don't want to convert the remaining ampersands but I just don't see how this is so. Either the HTML content is a string you want to process -- in which case, all of it should be escaped so that it can be unescaped later -- or it's valid XML that you want to be part of the document. I mean, when you process the contents of the <content> tag later on, you will run into problems if the ampersands aren't escaped.

Unfortunately this answer:

<cfxml variable="myXML">
    <content><![CDATA[#myHTML#]]></content>
</cfxml>

is insufficient if you happen to have invalid html that you want to display. consider the case where myHTML contains:

<p>some invalid html ]]><script>alert('foo')</script>

As far as I can tell there is no supported way in coldfusion to do proper encoding of potentially invalid data. Your best bet is to write yourself a filter function that entity encodes html special and illegal characters.

It's tough when you have some HTML partially converted, and then need to do the rest...

You could replace all the "&" signs temporarily, run the XMLFormat, then convert the "&" signs back.

<cfscript>
// replace & signs with a temp placeholder
myHTML = replace(myHTML, "&", "*amp*", "all");

// format for XML
myHTML = XMLFormat(myHTML);

// replace placeholders with & signs
myHTML = replace(myHTML, "*amp*", "&", "all");
</cfscript>

If it works, you could make this one step by wrapping this logic in a single function.

How about simply not using &mdash; escape in the source string and instead including the ?? character in-situ.

Edit :

I'm gonna guess that the HTML content stored in the database is not known to be XHTML compliant and hence to put it in an XML document you have no choice but to either place it in a CDATA section or encode it correctly. There is an assumption that placing it in an XML document like this is useful and that it can be properly decoded at the consuming end. This will be true of either approach if a typical XML DOM is used at the consumer.

So this leads me to this quesion, whats actually wrong with &amp;mdash ? After all < will result in &lt; etc. When retrieved from a DOM by the consumer the resulting string will be returned to using &mdash; and < and so on, when subsequently used in as HTML all will be well.

HTMLEditFormat(string) should convert your less-than and greater-than signs, but will also handle the ampersand. I understand that you want to leave the &mdash; as-is. It is worth pointing out that &mdash; is not one of XML's predefined entities (although you can define it).

I just thought I'd mention it, as HTMLEditFormat() is ideal for escaping HTML to include in XML documents, such as Atom feeds. It sounds like it is not the solution for your specific use case, however.

目前,我只是分别用“ &lt; ”和“ &gt; ”替换所有小于和大于字符的字符。

In this specific use case, you can use URLEncodedFormat() to preserve the natural form of the content, and then use URLDecode() on the way out.

<cfxml variable="content">
    <content><cfoutput>#URLEncodedFormat(myHTML)#</cfoutput></content>
</cfxml>
<cfset xml = xmlParse(content)>
<cfoutput>#URLDecode(xml.content.xmltext)#</cfoutput>

I'm not recommending this as a best practice, only that it would work in the scenario posed by the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM