【问题标题】:Javascript to add cdata section on the fly?Javascript动态添加cdata部分?
【发布时间】:2011-01-17 19:21:20
【问题描述】:

我遇到了 xml 节点属性中存在的特殊字符的问题。为了解决这个问题,我尝试将属性呈现为子节点,并在必要时使用 cdata 部分来绕过特殊字符。问题是,我似乎无法正确地将 cdata 部分附加到节点。

我正在迭代源 xml 节点的属性并创建新节点。如果 attribute.name = "description" 我想将 attribute.text() 放在 cdata 部分并附加新节点。这就是我跳过赛道的地方。

     // newXMLData is the new xml document that I've created in memory
    for (var ctr =0;ctr< this.attributes.length;ctr++){  // iterate over the attributes 
          if( this.attributes[ctr].name =="Description"){   // if the attribute name is "Description" add a CDATA section 
             var thisNodeName =  this.attributes[ctr].name;
               newXMLDataNode.append("<"+thisNodeName +"></"+ thisNodeName +">" );
               var cdata = newXMLData.createCDATASection('test');  // here's where it breaks. 
          } else {
           // It's not "Description" so just append the new node.
            newXMLDataNode.append("<"+ this.attributes[ctr].name +">" + $(this.attributes[ctr]).text() + "</"+ this.attributes[ctr].name +">"   );  
          }        
        } 

有什么想法吗?还有其他方法可以添加 cdata 部分吗?

这是源代码的示例 sn-p...

<row 
pSiteID="4" 
pSiteTile="Test Site Name " 
pSiteURL="http://www.cnn.com"
ID="1" 
Description="<div>blah blah blah since June 2007.&amp;nbsp; T<br>&amp;nbsp;<br>blah blah blah blah&amp;nbsp; </div>" 
CreatedDate="2010-09-20 14:46:18" 
Comments="Comments example.&#10;" >

这就是我要创建的...

<Site>
<PSITEID>4</PSITEID>
<PSITETILE>Test Site Name</PSITETILE>
<PSITEURL>http://www.cnn.com</PSITEURL>
<ID>1</ID>
<DESCRIPTION><![CDATA[<div>blah blah blah since June 2007.&amp;nbsp; T<br>&amp;nbsp;<br>blah blah blah blah&amp;nbsp; </div ]]></DESCRIPTION>
<CREATEDDATE>2010-09-20 14:46:18</CREATEDDATE>
<COMMENTS><![CDATA[ Comments example.&#10;]]></COMMENTS>
</Site>

【问题讨论】:

  • 能否在添加 CDATA 前后显示一些 XML?
  • 如果您的 XML 格式不正确,那么您有两个问题..
  • 这并没有真正的帮助。我正在尝试从格式不正确的 xml 生成格式正确的 xml。因此是 CDATA。

标签: javascript jquery xml append cdata


【解决方案1】:

我有同样的问题。我试图将 CDATA 附加到 xml 节点,所以我认为它就像添加这样简单:

valueNode[0].text = "<![CDATA["+ tmpVal +"]]>";
//valueNode[0] represents "<value></value>"

这不起作用,因为整个内容将被解释为文本,因此 (大于) 将被自动替换。

您需要做的是通过执行以下操作来使用 createCDATASection:

var tmpCdata = $xmlDoc[0].createCDATASection(escape("muzi test 002"));
//i'm also escaping special charactures as well
valueNode[0].appendChild(tmpCdata);

结果将是:

<value><![CDATA[muzi%20test%20002]]></value>

Brettz9(在上一个答案中)解释了如何做到这一点,但非常复杂,因此我只想添加我的解决方案,它更简单。

谢谢,

【讨论】:

    【解决方案2】:

    不确定浏览器是否支持 document.implementation.createDocument 或 createCDataSection,但这至少在 Mozilla 中有效:

    <script>
    
        // Define some helpers (not available IE < 9)
        function parse (str) {
            return new DOMParser().parseFromString(str, 'text/xml').documentElement;
        }
        function ser (dom) {
            return new XMLSerializer().serializeToString(dom);
        }
    
        // Simulate your XML retrieval
        var row = '<row pSiteID="4" pSiteTile="Test Site Name " pSiteURL="http://www.cnn.com" ID="1" Description="<div>blah blah blah since June 2007.&amp;nbsp; T<br>&amp;nbsp;<br>blah blah blah blah&amp;nbsp; </div>" CreatedDate="2010-09-20 14:46:18" Comments="Comments example.&#10;" />';
    
        // Hack to convert source to well-formed XML, or otherwise you can't use DOM methods on it which
        // depend on well-formed XML
        row = row.replace(/(=\s*")([\s\S]*?)(")/g, function (n0, n1, n2, n3) {
            return n1+ // Add back equal sign and opening quote
                n2.replace(/</g, '&lt;'). // Create well-formed XML by avoiding less-than signs inside attributes
                replace(/&amp;nbsp;/g, '&amp;#160;')+ // HTML entities (except for gt, lt, amp, quot) must be either converted to numeric character references or your XML must define the same entities
                n3; // Add back closing quote
        });
    
        // Simulate your retrieval of DOM attributes, though in this context, we're just making attributes into a global
        this.attributes = parse(row).attributes;
    
        // Simulate your creation of an XML document
        var newXMLData = document.implementation.createDocument(null, 'Site', null);
    
        // Modify your code to avoid jQuery dependency for easier testing and to 
        // avoid confusion (error?) of having two variables, newXMLData and newXMLDataNode
        for (var ctr =0;ctr< this.attributes.length;ctr++){  // iterate over the attributes 
          if (this.attributes[ctr].name =="Description") {   // if the attribute name is "Description" add a CDATA section 
             var thisNodeName =  this.attributes[ctr].name;
             var str = "<"+thisNodeName +"></"+ thisNodeName +">";
             var node = parse(str);
             var cdata = newXMLData.createCDATASection(this.attributes[ctr].textContent);
             node.appendChild(cdata);
             newXMLData.documentElement.appendChild(node);       
          }
          else {
           // It's not "Description" so just append the new node.
            var str= "<"+ this.attributes[ctr].name +">" + this.attributes[ctr].textContent + "</"+ this.attributes[ctr].name +">";
            newXMLData.documentElement.appendChild(parse(str));
          }
        } 
        // Prove its working (though you may wish to use toUpperCase() if you need the element names upper-cased); 
        // if you need CDATA for Comments, you can follow the pattern above to add support for that too
        alert(ser(newXMLData)); 
    </script>
    

    【讨论】:

      猜你喜欢
      • 2013-11-16
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      相关资源
      最近更新 更多