如何在XSLT生成的HTML/JS中正确输出保留字符<
解决XSLT生成JS时
<转义失效问题 问题背景
旧XSLT文件负责将XML转换为HTML/JS,当前存在以下问题:
- 生成的JS代码中
<未被转换为<,导致现代浏览器中JS逻辑失效 - 直接将XSLT中的
<替换为<会触发XML语法错误 - 尝试通过带
disable-output-escaping="yes"的变量输出<,但HTML输出仍为<(已启用HTML序列化方式)
原生成的失效JS代码
function processVisibility(item, visible) { var childs = item.childNodes; for (var i = 0; i < childs.length; i++) { if ( (childs.item(i).className == "ArchiveObject") || (childs.item(i).className == "Document") || (childs.item(i).className == "Attachment") ) { if (visible) { childs.item(i).style.display = "block"; } else { childs.item(i).style.display = "none"; } } } }
原XSLT关键代码片段
<xsl:stylesheet version="1.0" xmlns:sada="sada:v1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ccts="urn:un:unece:uncefact:documentation:standard:CoreComponentsTechnicalSpecification:2" exclude-result-prefixes="sada xsl xsd ccts"> <xsl:output method="html" indent="yes" media-type="text/html" encoding="UTF-8"/> <xsl:template match="/"> <html> <head> <script type="text/javascript"> function processVisibility(item, visible) { var childs = item.childNodes; for (var i=0; i&lt;childs.length; i++) { if ( (childs.item(i).className == "ArchiveObject") || (childs.item(i).className == "Document") || (childs.item(i).className == "Attachment") ) { if (visible) { childs.item(i).style.display = "block"; } else { childs.item(i).style.display = "none"; } } } } </script> <title>Standard (SADA)</title> </head> <body> <xsl:apply-templates /> </body> </html> </xsl:template> </xsl:stylesheet>
解决方案
方法1:使用CDATA块包裹JS代码(推荐)
HTML的<script>标签支持CDATA块,XSLT会原样输出CDATA内部的内容,不会转义特殊字符。直接将JS代码放入<![CDATA[ ]]>中即可:
<script type="text/javascript"> <![CDATA[ function processVisibility(item, visible) { var childs = item.childNodes; for (var i=0; i<childs.length; i++) { if ( (childs.item(i).className == "ArchiveObject") || (childs.item(i).className == "Document") || (childs.item(i).className == "Attachment") ) { if (visible) { childs.item(i).style.display = "block"; } else { childs.item(i).style.display = "none"; } } } } ]]> </script>
方法2:使用<xsl:text>标签单独处理特殊字符
针对单个需要输出<的位置,用<xsl:text>标签包裹并开启disable-output-escaping="yes":
<script type="text/javascript"> function processVisibility(item, visible) { var childs = item.childNodes; for (var i=0; i<xsl:text disable-output-escaping="yes"><</xsl:text>childs.length; i++) { if ( (childs.item(i).className == "ArchiveObject") || (childs.item(i).className == "Document") || (childs.item(i).className == "Attachment") ) { if (visible) { childs.item(i).style.display = "block"; } else { childs.item(i).style.display = "none"; } } } } </script>
方法3:定义带转义禁用的变量
先定义包含<的变量,再在JS中引用:
<!-- 在stylesheet内定义变量 --> <xsl:variable name="lt"> <xsl:text disable-output-escaping="yes"><</xsl:text> </xsl:variable> <!-- 在JS代码中引用变量 --> <script type="text/javascript"> function processVisibility(item, visible) { var childs = item.childNodes; for (var i=0; i<xsl:value-of select="$lt"/>childs.length; i++) { if ( (childs.item(i).className == "ArchiveObject") || (childs.item(i).className == "Document") || (childs.item(i).className == "Attachment") ) { if (visible) { childs.item(i).style.display = "block"; } else { childs.item(i).style.display = "none"; } } } } </script>
验证说明
以上三种方法均可让XSLT生成的HTML中,JS代码里的<正常显示,不会被转义为<,确保现代浏览器能正确解析执行JS逻辑。优先推荐方法1,无需逐个处理特殊字符,代码维护更简单。
内容的提问来源于stack exchange,提问作者Pick
相关产品推荐
相关产品推荐

