替换' &安培; '到' &安培; '来自javascript中的xml

时间:2014-03-28 10:15:09

标签: javascript xml parsing dom special-characters

我正在尝试使用javascript解析动态xml文件。但<link>元素中的url包含ambersant符号(&amp;)  所以我必须创建一个函数来动态替换符号“&”和“&amp;”。

你有什么想法我会怎么做?

这是整个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);
 }
};

3 个答案:

答案 0 :(得分:3)

你向我们展示的“xml”并不是格式良好的XML(也就是说,它根本不是XML)。 XML解析器需要拒绝格式错误的XML。正确的方法是找出流氓应用程序正在生成此损坏数据,并在源头修复问题。一旦人们开始发送(并接受!)错误的XML,使用标准交换格式的好处就会迅速消失。

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

答案 1 :(得分:0)

如果您想知道您在上述评论中已有的功能如何运作:

return unsafe.replace(/&/g, "&amp;");
unsafe 所有replace lobal修饰符)正则表达式g(与文字匹配)匹配后,

返回/&/ &符号"&amp;"

答案 2 :(得分:0)

我在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?

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

如果您决定忽略此建议,那么一种方法是将文件读入String,使用String.replaceAll(正则表达式,替换)和合适的正则表达式扭转这些虚假的&#34;&amp;&#34;将字符转换为正确的字符实体(&#34;&amp;&#34;),然后将固定的XML字符串提供给XML解析器。您需要仔细设计正则表达式,以便它不会将有效的字符实体破坏为不必要的副作用。第二种方法是手工进行解析和替换,使用适当的启发法来区分伪造的&#34;&amp;&#34;来自格式良好的字符实体的字符。

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