开发者

XSLT, Doctype and Google-Map v3 not working

I'm trying to include a GoogleMap v3 (everything was okay with v2) in my HTML pages generated with XLS Transformations. My JS code comes from this page.

Basically, the map works correctly when everything is in plain HTML, as per the example, however when I try to include it in the XSL stylesheet, Firefox (v3.6) complains and doesn't want to load anything:

Error: uncaught exception: [Exception... "Operation is not supported" code: "9" nsresult: "0x80530009 (NS_ERROR_DOM_NOT_SUPPORTED_ERR)" location: "http://maps.google.com/maps/api/js?sensor=false Line: 9"]

Error: google.maps.LatLng is not a constructor Source File: file:///home/kevin/google/data.xml Line: 2

Here is a simplified version of the XSL code I'm using:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xsl:stylesheet >
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <head>
         <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
         <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
         <style type="text/css">
      html { height: 100% }
      body { height: 100%; margin: 0px; padding: 0px }
      #map_canvas { height: 100% }
         </style>
         <title>Google Maps JavaScript API v3 Example: Map Simple</title>
         <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
         <script type="text/javascript">
      function initialize() {
      var myLatlng = new google.maps.LatLng(-34.397, 150.644);
      var myOptions = {
      zoom: 8,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
      }
      var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
      }
         </script>
      </head>
      <body onload="initialize()">
        <div id="map_canvas"></div>
       </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

and a minimalist XML document to trigger the transformation:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xsl:stylesheet>
<?xml-stylesheet type="text/xsl" href="Display.xsl"?>
<root />

According to my Google investigations, the problem might come from a wrong Doctype, but I don't really know how to fix it, functions like

<xsl:output method="html"
    indent="yes"
    omit-xml-declaration="yes"
    encoding="utf-8"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" />

don't change anything.

EDIT: my actual DOCTYPE is slightly more comple, for XML:

<!DOCTYPE xsl:stylesheet  [<!ENTITY auml   "&#228;" ><!ENTITY ouml   "&#246;" ><!ENTITY uuml   "&#252;" ><!ENTITY szlig  "&#223;" ><!ENTITY Auml   "&#196;" ><!ENTITY Ouml   "&#214;" ><!ENTITY Uuml   "&#220;" ><!ENTITY euml   "&#235;" ><!ENTITY ocirc  "&#244;" ><!ENTITY nbsp   "&#160;" ><!ENTITY Agrave "&#192;" ><!ENTITY Egrave "&#200;" ><!ENTITY Eacute "&#201;" ><!ENTITY Ecirc  "&#202;" ><!ENTITY egrave "&#232;" ><!ENTITY eacute "&#233;" ><!ENTITY ecirc  "&#234;" ><!ENTITY agrave "&#224;" ><!ENTITY iuml   "&#2开发者_C百科39;" ><!ENTITY ugrave "&#249;" ><!ENTITY ucirc  "&#251;" ><!ENTITY uuml   "&#252;" ><!ENTITY ccedil "&#231;" ><!ENTITY AElig  "&#198;" ><!ENTITY aelig  "&#330;" ><!ENTITY OElig  "&#338;" ><!ENTITY oelig  "&#339;" ><!ENTITY euro   "&#8364;"><!ENTITY laquo  "&#171;" ><!ENTITY raquo  "&#187;" >]>

and XSL:

<!DOCTYPE xsl:stylesheet  [
  <!ENTITY % xhtml-lat1 SYSTEM
     "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
  <!ENTITY % xhtml-special SYSTEM
     "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
  <!ENTITY % xhtml-symbol SYSTEM
     "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
  %xhtml-lat1;
  %xhtml-special;
  %xhtml-symbol;
  ]>

to handle correctly all my accents and special chars, so I'd like to avoid getting rid of it, if possible

EDIT 2: the problem is actually exactly the same with I try to load an OpenStreetMap though Mapstraction API, document.write is not allowed.

Another thing it that Google Map v2 works correctly when I use a callback function:

http://maps.google.com/maps?file=api&v=2.x&key={myKey}&c&async=2&callback={myInitFunct}

Any clue about what can be wrong?


the solution is to use the callback parameter of the GoogleMap API:

http://maps.google.com/maps/api/js?sensor=false&callback={myInitFunction}

Indeed, as we can see in the generated JS script, they don't insert their code the same way:

With callback:

function getScript(src) {
    var s = document.createElement('script');

    s.src = src;
    document.body.appendChild(s);
  }

Without callback:

function getScript(src) {
document.write('<' + 'script src="' + src + '"' +
               ' type="text/javascript"><' + '/script>');
}

where document.write might be forbidden ...

(however, I don't really understand why they use two different code for the same action, maybe just to solve our problem :)

thanks to this blog for the tutorial


The correct way to declare stylesheet DOCTYPE:

<!DOCTYPE xsl:stylesheet [ 
  <!ENTITY % HTMLlat1 PUBLIC
       "-//W3C//ENTITIES Latin 1 for XHTML//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
  %HTMLlat1;
  <!ENTITY % HTMLspecial PUBLIC
        "-//W3C//ENTITIES Special for XHTML//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
  %HTMLspecial;
  <!ENTITY % HTMLsymbol PUBLIC
        "-//W3C//ENTITIES Symbols for XHTML//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
  %HTMLsymbol;
]>


The issue here is that the XSLT output in FF does not behave like static HTML.

In a static HTML page, the GMap script is loaded synchronously so that, when the body.onload event fires, the script is already loaded.

In the XSLT output, the script is still loading when body.onload fires.

I worked around the issue this way (what follows is the XSLT output):

<html>
<head>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;callback=onLoadCode"></script>
    <script type="text/javascript">
        function onLoadMaps()
        {
            /// init the maps here
        }

        var zOnLoadCode = false;
        var zOnLoadBody = false;
        function onLoadCode() { zOnLoadCode = true; }
        function onLoadBody() { zOnLoadBody = true; }
        var onLoadTimer = window.setInterval(function() {
            if(zOnLoadCode && zOnLoadBody) {
                window.clearInterval(onLoadTimer);
                onLoadMaps();
            }
        },100,"javascript");
    </script>
</head>
<body onload="onLoadBody();">
    <!-- put your maps here -->
</body>

That is, I used the GMap callback URL param to signal when the script is loaded and the body.onload event to signal when the page is ready, then I wait until both have been fired.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜