【问题标题】:replace ' & ' to ' & ' from xml in javascript在javascript中将'&'从xml替换为'&'
【发布时间】:2014-03-28 10:15:08
【问题描述】:

我正在尝试使用 javascript 解析动态 xml 文件。但是 <link> 元素内的 url 包含琥珀色符号 ( & )。
所以我必须创建一个函数,用'&'动态替换符号'&'。

你知道我要怎么做吗?

这是整个html文件

<html>
    <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>metar.gr</title>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript" src="util.js"></script>
    <script src="js/libs/require.js" data-main="js/mobile"></script>
    <link rel="stylesheet" href="https://d10ajoocuyu32n.cloudfront.net/mobile/1.3.1/jquery.mobile-1.3.1.min.css"/>
    <link rel="stylesheet" href="fonts-and-colors.css" type="text/css" media="screen">
    <script type="text/javascript">
      var infowindow;
      var map;

      function initialize() {
        var myLatlng = new google.maps.LatLng(38.822590,24.653320);
        var myOptions = {
          zoom: 6,
          center: myLatlng,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

        downloadUrl("moredata.xml", function(doc) {
          var items = doc.documentElement.getElementsByTagName("item");
          for (var i = 0; i < items.length; i++) {
            var description = items[i].getElementsByTagName("description")[0].textContent;
            var temp        = items[i].getElementsByTagName("temp")[0].textContent;
            var title       = items[i].getElementsByTagName("title")[0].textContent;
            var link       = items[i].getElementsByTagName("link")[0].textContent;
            var windSpeed   = items[i].getElementsByTagName("windSpeed")[0].textContent;
            var dailyRain   = items[i].getElementsByTagName("dailyRain")[0].textContent;
            var latlng      = new google.maps.LatLng(parseFloat(items[i].getElementsByTagName("glat")[0].textContent),
                                                     parseFloat(items[i].getElementsByTagName("glon")[0].textContent));

            if ( temp <= "1 °C" ) {
              //alert(temp);
              var marker = createMarker( temp,latlng,cold );
              }

            if ( temp >= "38 °C" ) {
              //alert(temp);
              var marker2 = createMarker2( temp,latlng,hot );
              }
           }
         });
      }
      var cold  = 'weather_icons/pagetos2.png';
      var hot   = 'weather_icons/hot.png';

      function createMarker( temp,latlng,cold ) {
        var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: cold
        });

        google.maps.event.addListener(marker, "click", function() {
          if (infowindow) infowindow.close();
          infowindow = new google.maps.InfoWindow({
          content: temp
          });
          infowindow.open(map, marker);
        });
        return marker;
      }

      function createMarker2( temp,latlng,hot ) {
        var marker2 = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: hot
        });

        google.maps.event.addListener(marker2, "click", function() {
          if (infowindow) infowindow.close();
          infowindow = new google.maps.InfoWindow({
          content: temp
          });
          infowindow.open(map, marker2);
        });
        return marker2;
      }

</script>
</head>
<body onload="initialize()">
    <div data-role="header" data-theme="b">
        <div align="center">
                     <img  onclick='doAction("showStoreLocatorMap()")' src="http://www.metar.gr/templates/metar/images/metar.gif"  alt="main logo" vspace="2"/>
        </div>
        <a href="main.html" data-role="button" data-inline="true">Home</a>
    </div>
    <div data-role="content">
            <div id="map_canvas" ></div>    
    </div>
        <div data-role="info_icons">
        <ul data-role="listview" id="icon_info" data-theme="c"> 
        <img src="weather_icons/pagetos2.png"/>  
        <h3 class="ui-li-heading">Cold</h3>  
        <p class="ui-li-desc">temprature < +4° C</p>
        </li> 
        <li>
        <img src="weather_icons/hot.png"/>  
        <h3 class="ui-li-heading">Hot</h3>  
        <p class="ui-li-desc">temprature > +38° C</p>
        </li>       
        </ul>
        </div>
    <div data-role="footer" data-theme="b">
        <h4>metar.gr mobile version</h4> 
    </div>
</body>
</html>

xml文件示例

 <item>
      <description>Thesaloniki</description>
      <glat>40.422726139672626</glat>
      <glon>22.93392777442932</glon>
      <title>makedonia</title>
      <temp>60  °C</temp>
      <dailyRain>0 mm</dailyRain>
      <windSpeed>3.1 km/hr</windSpeed>
      <link>
         http://www.metar.gr/index.php?option=com_jumi&fileid=12&Itemid=73&station=1475
      </link>
  </item>
  <item>
      <description>Giannena</description>
      <glat>39.62209843837158</glat>
      <glon>20.89027225971222</glon>
      <title>ipiros</title>
      <temp>-16.9°C</temp>
      <dailyRain>0.0 mm</dailyRain>
      <windSpeed>10 km/hr</windSpeed>
      <link>
          http://www.metar.gr/index.php?option=com_jumi&fileid=12&Itemid=73&station=1227
      </link>
  </item>
  <item>
      <description>Athina</description>
      <glat>38.08469095792561</glat>
      <glon>23.680233657360077</glon>
      <title>sterea</title>
      <temp>45°C</temp>
      <dailyRain>0.0 mm</dailyRain>
      <windSpeed>97  km/hr</windSpeed>
      <link>
         http://www.metar.gr/index.php?option=com_jumi&fileid=12&Itemid=73&station=1009
      </link>
  </item>

util.js 文件的一部分

function downloadUrl(url, callback) {
 var status = -1;
 var request = createXmlHttpRequest();
 if (!request) {
   return false;
 }

 request.onreadystatechange = function() {
   if (request.readyState == 4) {
     try {
       status = request.status;
     } catch (e) {
       // Usually indicates request timed out in FF.
     }
     if (status == 200) {
       callback(request.responseXML, request.status);
       request.onreadystatechange = function() {};
     }
   }
 }
 request.open('GET', url, true);
 try {
   request.send(null);
 } catch (e) {
   changeStatus(e);
 }
};

【问题讨论】:

  • 我不明白。 解析 XML 时为什么需要htmlSpecialChars?你刚刚解析了它,并且有一个简单的值(这很好!)。你打算用link做什么?
  • @Bergi — XML 无效,需要修复才能解析。
  • @Quentin:即使是这样,downloadURL 也需要处理它,而不是通过解析的 doc 传递的回调。
  • @Bergi — 理想情况下是这样,但第三方内容并不那么容易修复。
  • @Bergi 这是一个真实的 xml 样本。这次我不需要使用 。但问题是我无法编辑 xml 文件。所以 必须保留。

标签: javascript xml parsing dom special-characters


【解决方案1】:

您向我们展示的“xml”不是格式良好的 XML(也就是说,它根本不是 XML)。 XML 解析器需要拒绝格式错误的 XML。正确的方法是找出产生这些损坏数据的恶意应用程序,并从源头上解决问题。一旦人们开始发送(并接受!)糟糕的 XML,使用标准交换格式的好处就会很快消失。

如果你不能这样做,你需要编写一个修复工具。因为您的数据不是 XML,所以您不能使用 XML 工具来完成这项工作;使用 Perl 之类的东西。详细信息将取决于您希望在 XML 中出现什么样的错误,例如您是否只需要处理未转义的 & 符号,或者还需要处理未声明的实体引用,例如 &amp;nbsp;

【讨论】:

  • 。xml 文件不是我自己创建的。我的教授让我创建一个移动网站。所以,我无法编辑或修复它。我的水平在 javascript - xml 世界中非常基础,我正在尝试解析它。
  • 要么让你的教授修改它,要么在你自己的帐户上修改它,要么提供它的预处理版本。
  • 教授会犯错误,如果她/他是一位称职的专业人士,那么她/他会很高兴被告知错误。她/他也会因为指出错误而对你评价更高。
【解决方案2】:

如果您想知道上面评论中已有的功能是如何工作的:

return unsafe.replace(/&/g, "&amp;");

返回unsafe,在replaceing 所有global 修饰符)匹配正则表达式/&amp;/(匹配文字和符号)与"&amp;amp;"

【讨论】:

  • 那么,这是我需要的功能吗?我将如何将它插入到我的代码中?
【解决方案3】:

我在 stackoverflow 中找到了一个类似问题的答案并引用了它。我必须将 xml 文件读入 String.replace
看看吧!

您尝试读取的文件不是有效的 XML。没有自尊的 XML 解析器会接受它。

  I'm retrieving my XML dynamically from the web. What's the best way to replace all my escape  
characters after fetching the Document object?

您采取了错误的方法。正确的方法是通知负责创建该文件的人员该文件无效,并要求他们修复它。简单地编写 hack 来(尝试)修复损坏的 XML 不符合您(或其他人)的长期利益。

如果您决定忽略此建议,那么一种方法是将文件读入字符串,使用 String.replaceAll(regex, replacement) 和合适的正则表达式将这些伪造的“&”字符转换为正确的字符实体(“&”),然后将固定的 XML 字符串提供给 XML 解析器。您需要仔细设计正则表达式,使其不会破坏有效的字符实体作为不需要的副作用。第二种方法是手动进行解析和替换,使用适当的启发式方法将伪造的“&”字符与格式正确的字符实体区分开来。

但这一切都会花费您的开发和测试时间,并减慢您的软件速度。更糟糕的是,由于您努力补偿错误的输入文件,您的代码很可能会变得脆弱。 (猜猜谁会受到指责……)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 2013-01-23
    • 2013-11-25
    相关资源
    最近更新 更多