Javascript 内部代码&;书信电报;在属性上

Javascript 内部代码&;书信电报;在属性上,javascript,html,xml,xslt,innerhtml,Javascript,Html,Xml,Xslt,Innerhtml,我有一个HTML文档,它的某些属性中可能包含和。我试图提取它并通过XSLT运行它,但是XSLT引擎错误地告诉我,我不确定这是否是您正在查找的内容,但请确实查看一下 var div1 = document.createElement('DIV'); var div2 = document.createElement('DIV'); div1.setAttribute('asdf','<50'); div1.setAttribute('fdsa','&50'); di

我有一个HTML文档,它的某些属性中可能包含
。我试图提取它并通过XSLT运行它,但是XSLT引擎错误地告诉我,
我不确定这是否是您正在查找的内容,但请确实查看一下

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, '&'));
尝试:

var div=document.getElementById('d1');
var pre=document.createElement('pre');
pre.textContent=div.outerHTML;
文件.正文.附件(pre);
pre=document.createElement('pre');
pre.textContent=新的XMLSerializer().serializeToString(div);
文件.正文.附件(pre)

这是一个测试
对我来说最有效的方法是在传入文档中使用XSLT双重转义这些内容(并在传出文档中反向转义)

因此属性中的
变为
&;lt。感谢@Abel的建议

以下是我添加的XSLT,以防其他人发现它有帮助:

第一个是在XSLT1.0中进行字符串替换的模板。如果可以使用XSLT2.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>

接下来是执行我需要的特定替换的模板:

<!-- 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="'&lt;'"/>
            <xsl:with-param name="by" select="'&amp;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="'&gt;'"/>
            <xsl:with-param name="by" select="'&amp;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="'&amp;lt;'"/>
            <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="'&amp;gt;'"/>
            <xsl:with-param name="by" select="'&gt;'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$gt"/>
</xsl:template>

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>

有几件值得一提的事情可能会对某人有所帮助:

  • 请确保您的HTML是真正有效的,例如,我本应使用
    /
    时意外使用了
    \
    ,这导致了此问题
  • 正如问题中的OP所指出的,您可以使用
    &
    ,因此您可以尝试,例如
    &;lt
    &;燃气轮机
  • 有to
    看起来很相似
  • 有一种方法可以表达
    <
    >

@Abel我正在使用jQuery的
.html()
,我只是试图把问题缩小到我认为“问题”发生的地方。源文档是XML,在使用
.html()
插入之前,我通过浏览器XSLT运行了它。稍后,我将通过相反的过程来获取XML。我只是觉得奇怪的是DOM没有回避这个字符(而不是其他字符)。我不能修改源XML,需要在输出的最后保留相同的内容。我可以运行任何必要的转换在中间,但我正在寻找一种方法来做它比一些正则表达式取代。特别是考虑到角色是
@Abel,我唯一的目标是以它进入DOM的方式将其从DOM中恢复(如
)。我用
.text(string)
输入,用
.text()
输出。这个往返的问题是输入不等于输出(仅在这种情况下)。啊,对不起。这可能只适用于其他DOM方法,而不适用于
innerHTML
。也就是说,这是有效的:
div.firstChild.attributes['title']
。但这需要大量额外的机器来“模仿”innerHTML。我看不出这如何回答属性中转义少于字符的问题。。。而且你可能不想让每一个符号都被替换掉……实际上,它可以转换和&;至&;书信电报;及;amp;分别地replace函数将其更改回原始格式。这正是我的观点<代码>&
仅当它是属性值的一部分时才应替换,就像字符串被解释为XML一样。它不应该取代其他出现的内容(文本节点、注释节点、处理指令、cdata节,尽管其中一些在HTML中很少见)。我感到沮丧的是,对于相同的文本
,setAttribute
的行为与
innerHTML
不同。我相信这就是@Abel所说的在一种情况下被解释为“HTML”,而在另一种情况下则不是的意思。@murrayju,是的,
innerHTML
是DOM中非常不幸的一部分。几乎所有其他DOM属性都以XML的形式在DOM上工作,但
innerHTML
不能。它在某些情况下很方便,特别是作为setter,但它不返回XML(正如您已经发现的那样)。这更接近我想要的,但它不能在所有浏览器中工作(IE8没有
XMLSerializer
)@murrayju,如果您必须支持用户份额<3%的(旧)浏览器,您可以,在这种情况下,只需使用
.xml
。我认为Martin Honnen的这个解决方案非常好:)。@Abel,我不认为IE或其他地方为HTML DOM节点实现了
xml
属性,它只存在于MSXML DOM节点。是的,这是我的观点,你必须为不支持XMLSerializer的浏览器破例(链接答案中显示了如何实现),虽然我没有用它来直接解决我的问题,但实现它可能也是一个好主意,因为它似乎比
innerHTML
更可靠。谢谢你的帮助!