我有一个HTML文档,在某些属性中可能包含<
和>
。我试图提取并通过XSLT运行它,但是XSLT引擎错误告诉我<
在属性中无效。
我做了一些挖掘,发现它在源文档中被正确转义,但是当它通过innerHTML
加载到DOM中时,DOM 取消属性。奇怪的是,它为<
和>
执行此操作,但不执行&
之类的其他操作。
这是一个简单的例子:
var div = document.createElement('DIV');
div.innerHTML = '<div asdf="<50" fdsa="&50"></div>';
console.log(div.innerHTML)
我假设DOM实现决定HTML属性可以不如XML属性严格,并且这是“按预期工作”。我的问题是,如果不写一些可怕的正则表达式替换,我可以解决这个问题吗?
答案 0 :(得分:2)
尝试使用XMLSerializer:
var div = document.getElementById('d1');
var pre = document.createElement('pre');
pre.textContent = div.outerHTML;
document.body.appendChild(pre);
pre = document.createElement('pre');
pre.textContent = new XMLSerializer().serializeToString(div);
document.body.appendChild(pre);
<div id="d1" data-foo="a < b && b > c">This is a test</div>
您可能需要调整XSLT以考虑XHTML命名空间XMLSerializer插入(至少在Firefox测试中)。
答案 1 :(得分:0)
我不确定这是不是你在看,但确实看看。
var div1 = document.createElement('DIV');
var div2 = document.createElement('DIV');
div1.setAttribute('asdf','<50');
div1.setAttribute('fdsa','&50');
div2.appendChild(div1);
console.log(div2.innerHTML.replace(/&/g, '&'));
答案 2 :(得分:0)
最适合我的是在传入文档上使用XSLT对其进行双重转义(并在传出文档中将其反转)。
属性中的if textField.isFirstResponder() { textField.becomeFirstResponder() }
else { textField.resignFirstResponder() }
变为<
。感谢@Abel的建议。
这是我添加的XSLT,以防其他人认为它有用:
首先是在XSLT 1.0中进行字符串替换的模板。如果您可以使用XSLT 2.0,则可以使用内置的&lt;
代替。
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>
XSLT主要是传递。我只是在复制属性时调用相应的模板:
<!-- 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>
答案 3 :(得分:0)
值得一提的几件事可能对某人有所帮助:
\
时,我不小心使用了/
,这引起了这个问题。&
,因此您可以尝试例如&lt;
和&gt;
。<
和>
看起来很相似。<
和>
的方式:<
和>
。