【问题标题】:Avoiding escaping character entity references when creating a text node in XML在 XML 中创建文本节点时避免转义字符实体引用
【发布时间】:2018-08-31 02:23:39
【问题描述】:

我正在使用 XML DOM 技术在 JavaScript 中构建下拉菜单。

创建<option> 节点后,我会附加应该为该选项显示的文本。我面临的问题是,当文本包含字符实体引用 (CER),例如 ₂ 时,CER 的 & 字符被转义为 &,因此选择菜单中显示的是 CER 而不是字符当菜单输出到页面显示时。

我尝试了以下两种方法: optionNode.appendChild(xmlDoc.createTextNode(label)); 和

optionNode.textContent = label;

两者都给出相同的结果。在将 XML 文档输出为文本后,我可以通过将 & 全局替换为 & 来解决此问题:

var xml = (new XMLSerializer()).serializeToString(xmlDoc);
return xml.replace(/&/g, '&');

但我敢肯定,首先必须有一种方法可以避免逃跑。有吗?

【问题讨论】:

    标签: xml escaping createtextnode


    【解决方案1】:

    您可以使用createCDATASection() 代替createTextNode()

    var docu = new DOMParser().parseFromString('<xml></xml>',  "application/xml")
    var cdata = docu.createCDATASection('Some <CDATA> data & then some');
    docu.getElementsByTagName('xml')[0].appendChild(cdata);
    
    alert(new XMLSerializer().serializeToString(docu));
    // Displays: <xml><![CDATA[Some <CDATA> data & then some]]></xml>
    

    【讨论】:

    • 也有同样的问题。
    • 是的,我试过了,但是我的字符串输出包含 ,它出现在下拉菜单中,所以我要重新进行全局替换。
    • 好吧,如果 CDATA 和实体有问题,听起来您不想要 XML 序列化。您如何阅读或应用输出?除非您不使用 XML api 进行读取,否则它应该被“读取”并毫无问题地解释。
    • 正如我所说,我正在构建一个下拉菜单,其中显示给用户的选项可能包含字符实体引用。我将从 XMLSerializer 获得的字符串附加到更大的 HTML 字符串中,然后使用 innerHTML 将更大的字符串(包括下拉菜单)放在页面上。如果序列化程序的 XML 输出包含 &#8322; (例如),它在下拉菜单中显示为 ₂。如果 XML 输出包含 ,它也会显式显示。
    【解决方案2】:

    我找到了解决方案。在创建包含label 的节点之前,我将label 中的所有字符实体引用转换为Unicode 字符。然后,当我将 xml 作为字符串输出时,我将所有 Unicode 字符转换回字符实体引用。代码改编自我找到的代码elsewhere on Stack Overflow

    function cerToUnicode(str) {
        "use strict";
        var entity_table = {
           '&quot;': String.fromCharCode(34), // Quotation mark. Not required
           '&amp;': String.fromCharCode(38), // Ampersand
                   '&lt;': String.fromCharCode(60), // Less-than sign
           '&gt;': String.fromCharCode(62), // Greater-than sign
           '&nbsp;': String.fromCharCode(160), // Non-breaking space
           '&iexcl;': String.fromCharCode(161), // Inverted exclamation mark
           ... // other named CERs
       };
       str = str.replace(/&#(\d+);/g,
           function (matched, capture1) {
               return (capture1 == '38' ? '&amp;' : String.fromCharCode(capture1));
           });
       str = str.replace(/&[^;]*;/g,
           function (matched) {
               return entity_table[matched];
           });
       return str;
    } // cerToUnicode()
    
    function unicodeToCER(str) {
        return str.replace(/./gm, function(s) {
            var code = s.charCodeAt(0);
            return (code < 128 ? s : "&#" + code + ";");
        });
    } // unicodeToCER()
    

    【讨论】:

      猜你喜欢
      • 2017-03-05
      • 2014-02-02
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 2016-10-30
      • 1970-01-01
      相关资源
      最近更新 更多