Google 从嵌套的 xml 列表映射信息窗口

Google maps infowindow from nested xml list

我需要从 xml 文件中的嵌套项 ('title') 填充 Google 地图信息窗口。 我可以很好地创建标记并在信息窗口中添加 'placeandsitename'。

这是我的 xml 的快照(完整的 xml 有多个 'location' 元素,每个元素都有各自的 'movie' 元素:

<locations>
<location lat="35.9027" lng="14.5179">
    <siteid>2</siteid>
    <placeandsitename>Valletta, Fort St Elmo</placeandsitename>
    <movie>
        <titleid>1</titleid>
        <title>13 Hours: The Secret Soldiers of Benghazi</title>
    </movie>
    <movie>
        <titleid>7</titleid>
        <title>Clash of the Titans</title>
    </movie>
    <movie>
        <titleid>9</titleid>
        <title>Cutthroat Island</title>
    </movie>
    <movie>
        <titleid>10</titleid>
        <title>A Different Loyalty</title>
    </movie>
    <movie>
        <titleid>25</titleid>
        <title>Midnight Express</title>
    </movie>
    <movie>
        <titleid>64</titleid>
        <title>World War Z</title>
    </movie>
</location>
<locations>

这是我的代码:

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        center: new google.maps.LatLng(35.933134, 14.3768843),  
          zoom: 11
    });
    var infoWindow = new google.maps.InfoWindow;

    downloadUrl('/data/locations_movies.xml', function (data) {
        var xml = data.responseXML;

        var markers = xml.documentElement.getElementsByTagName('location');
        Array.prototype.forEach.call(markers, function (markerElem) {

            var placeandsitename = markerElem.getElementsByTagName('placeandsitename')[0].childNodes[0];
            var point = new google.maps.LatLng(
                parseFloat(markerElem.getAttribute('lat')),
                parseFloat(markerElem.getAttribute('lng')));               

           // header for infowindow works fine!               
            var infowincontent = '<strong>' + placeandsitename.nodeValue + '</strong>'; 

// TODO: Create loop in Movie element and build list<li> element for infowindow (infowincontent)                

            var marker = new google.maps.Marker({
                map: map,
                position: point,
                title: placeandsitename.nodeValue                
            });          

            marker.addListener('click', function () {
                infoWindow.setContent(infowincontent);
                infoWindow.open(map, marker);
            });
        }); 
    });
}

在 'TODO' 部分,我想我需要为当前位置的 'title' 元素创建第二个循环,我不确定如何去做

以与解析 placeandsitename 相同的方式从 XML 中解析电影片名(只是不只使用第一个 [0],处理整个数组):

  // header for infowindow              
  var infowincontent = '<strong>' + placeandsitename.nodeValue + '</strong>'; // + movieList;
  // movie titles
  var movies = markerElem.getElementsByTagName('movie');
  if (movies.length > 0)
    infowincontent += "<table border=1>";
  for (var i=0; i<movies.length; i++) {
    infowincontent += "<tr><td>"+movies[i].getElementsByTagName('title')[0].childNodes[0].nodeValue+"</td></tr>";
  }
  if (movies.length > 0)
    infowincontent += "</table>";

proof of concept fiddle

代码片段:

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(35.933134, 14.3768843),
    zoom: 11
  });
  var infoWindow = new google.maps.InfoWindow();

  // downloadUrl('/data/locations_movies.xml', function(data) {
  //    var xml = data.responseXML;
  var xml = parseXml(xmlStr);

  var markers = xml.documentElement.getElementsByTagName('location');
  Array.prototype.forEach.call(markers, function(markerElem) {

    var placeandsitename = markerElem.getElementsByTagName('placeandsitename')[0].childNodes[0];
    var point = new google.maps.LatLng(
      parseFloat(markerElem.getAttribute('lat')),
      parseFloat(markerElem.getAttribute('lng')));

    // header for infowindow works fine!               
    var infowincontent = '<strong>' + placeandsitename.nodeValue + '</strong>'; // + movieList;
    var movies = markerElem.getElementsByTagName('movie');
    if (movies.length > 0)
      infowincontent += "<table border=1>";
    for (var i = 0; i < movies.length; i++) {
      infowincontent += "<tr><td>" + movies[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + "</td></tr>";
    }
    if (movies.length > 0)
      infowincontent += "</table>";
    // TODO: Create loop in Movie element and build list<li> element for infowindow (infowincontent)                

    var marker = new google.maps.Marker({
      map: map,
      position: point,
      title: placeandsitename.nodeValue
    });

    marker.addListener('click', function() {
      infoWindow.setContent(infowincontent);
      infoWindow.open(map, marker);
    });
    google.maps.event.trigger(marker, 'click');
  });
  //  });
}
google.maps.event.addDomListener(window, "load", initMap);

function parseXml(str) {
  if (window.ActiveXObject) {
    var doc = new ActiveXObject('MicrosoftXMLDOM');
    doc.loadXML(str);
    return doc;
  } else if (window.DOMParser) {
    return (new DOMParser).parseFromString(str, 'text/xml');
  }
};
var xmlStr = '<locations><location lat="35.9027" lng="14.5179"><siteid>2</siteid><placeandsitename>Valletta, Fort St Elmo</placeandsitename><movie><titleid>1</titleid><title>13 Hours: The Secret Soldiers of Benghazi</title></movie><movie><titleid>7</titleid><title>Clash of the Titans</title></movie><movie><titleid>9</titleid><title>Cutthroat Island</title></movie><movie><titleid>10</titleid><title>A Different Loyalty</title></movie><movie><titleid>25</titleid><title>Midnight Express</title></movie><movie><titleid>64</titleid><title>World War Z</title></movie></location><locations>';
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>