mur*_*yju 6 html javascript xml xslt innerhtml
我有可能有一个HTML文档<,并>在某些属性.我试图提取它并通过XSLT运行它,但XSLT引擎错误告诉我<在属性内部无效.
我做了一些挖掘,发现它在源文档中被正确转义,但是当它通过innerHTMLDOM 加载到DOM中时,DOM 就不会对属性进行编码.奇怪的是,它这样做的<和>,而不是一些人喜欢&.
这是一个简单的例子:
var div = document.createElement('DIV');
div.innerHTML = '<div asdf="<50" fdsa="&50"></div>';
console.log(div.innerHTML)Run Code Online (Sandbox Code Playgroud)
我假设DOM实现决定HTML属性可以不如XML属性严格,并且这是"按预期工作".我的问题是,如果不写一些可怕的正则表达式替换,我可以解决这个问题吗?
最终对我来说最有效的是在传入文档上使用 XSLT 进行双重转义(并在传出文档上反转)。
所以<在属性中就变成了&lt;. 感谢@Abel 的建议。
这是我添加的 XSLT,以防其他人发现它有帮助:
第一个是用于在 XSLT 1.0 中进行字符串替换的模板。如果您可以使用 XSLT 2.0,则可以使用内置的replace。
<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text, $replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
接下来是执行我需要的特定替换的模板:
<!-- xml -> html -->
<xsl:template name="replace-html-codes">
<xsl:param name="text"/>
<xsl:variable name="lt">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="$text"/>
<xsl:with-param name="replace" select="'<'"/>
<xsl:with-param name="by" select="'&lt;'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="gt">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="$lt"/>
<xsl:with-param name="replace" select="'>'"/>
<xsl:with-param name="by" select="'&gt;'"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$gt"/>
</xsl:template>
<!-- html -> xml -->
<xsl:template name="restore-html-codes">
<xsl:param name="text"/>
<xsl:variable name="lt">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="$text"/>
<xsl:with-param name="replace" select="'&lt;'"/>
<xsl:with-param name="by" select="'<'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="gt">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="$lt"/>
<xsl:with-param name="replace" select="'&gt;'"/>
<xsl:with-param name="by" select="'>'"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$gt"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
XSLT 主要是传递。我只是在复制属性时调用适当的模板:
<xsl:template match="@*">
<xsl:attribute name="data-{local-name()}">
<xsl:call-template name="replace-html-codes">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<!-- copy all nodes -->
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
858 次 |
| 最近记录: |