【问题标题】:using apply template within javascript在 javascript 中使用应用模板
【发布时间】:2014-02-26 08:50:19
【问题描述】:

我正在尝试创建一个在谷歌地图上显示 personell 的 html 页面。为了在地图上创建不同的标记,我有一个 javascript,它为数组位置中的每个条目创建一个标记。该数组应该填充来自 db(在 xml 中)的数据,并且必须转换为我的 html。

请看一下我的 xsl:

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
    <head>
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyB1tbIAqN0XqcgTR1-FxYoVTVq6Is6lD98&sensor=false"></script>
    <script type="text/javascript">
        var infos = [];
        var locations = [
            <xsl:apply-templates select='//rows'/>
        ];
        function initialize() {
            var myOptions = {
                center: new google.maps.LatLng(50.59, 4.35),
                zoom: 8,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("default"),myOptions);
            setMarkers(map,locations)
            }
        function setMarkers(map,locations){
            var marker, i
            for (i = 0; i < locations.length; i++)
            {   var name = locations[i][0]
                var long = locations[i][1]
                var lat = locations[i][2]
                var contentmarker =  locations[i][3]
                latlngset = new google.maps.LatLng(lat, long);
                var marker = new google.maps.Marker({
                    map: map, title: name , position: latlngset
                });
                map.setCenter(marker.getPosition())
                var content = contentmarker
                var infowindow = new google.maps.InfoWindow()
                google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){ 
                    return function() {
                    /* close the previous info-window */
                    closeInfos();
                    infowindow.setContent(content);
                            infowindow.open(map,marker);
                            /* keep the handle, in order to close it on next click event */
                            infos[0]=infowindow;
                    };
                })(marker,content,infowindow)); 
            }
        }
        function closeInfos(){
            if(infos.length &gt; 0){
                /* detach the info-window from the marker ... undocumented in the API docs */
                infos[0].set("marker", null);
                /* and close it */
                infos[0].close();
                /* blank the array */
                infos.length = 0;
            }
        }
        </script>
    </head>
    <body onload="initialize()">
        <div id="default" style="width:100%; height:100%"></div>
    </body>
</html>
</xsl:template>
<xsl:template match='rows'>
<xsl:for-each-group select='row' group-by='@SiteNr'>
    [&apos;<xsl:value-of select='@SiteName'/>&apos;, &apos;<xsl:value-of select='@LON_R'/>&apos;, &apos;<xsl:value-of select='@LAT_R'/>
    &apos;, &apos;&lt;b&gt;<xsl:value-of select='@RegionName'/>&lt;/b&gt;&lt;br&gt;Details (<xsl:value-of select='@SiteNr'/>):
    <table border='1'>
        <tr>
            <th>PersNr</th>
            <th>Name</th>
            <th>Firstname</th>
            <th>DeptNr</th>
            <th>DeptName</th>
            <th>PostNr</th>
        </tr>
        <xsl:for-each select="current-group()">
            <xsl:apply-templates select="."/>
                <tr>
                    <td><xsl:value-of select="@PersNr"/></td>
                    <td><xsl:value-of select="@Name"/></td>
                    <td><xsl:value-of select="@FirstName"/></td>
                    <td><xsl:value-of select="@DeptCode"/></td>
                    <td><xsl:value-of select="@DeptName"/></td>
                    <td><xsl:value-of select="@PostNr"/></td>
                </tr>
        </xsl:for-each>
        <tr>
            <td colspan='5'>TOTAAL</td>
            <td align='center'><xsl:value-of select="(count(current-group()/@PersNr))"/></td>
        </tr>
    </table>&apos;] 
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>

如果我在脚本周围尝试 CDATA,它会运行,但我的脚本标签会用 进行转换,并且脚本不再工作。

我的 xml 的摘录:

<rows>
    <row PersNr="B15975" Name="Vandendriessche" Firstname="Rudolf" DeptCode"J20100" DeptName="HR" Post="1230" RegionNum="3" RegionName="Plateau Berlaar" SiteNum="11002D" SiteName="KW BELGIELEI" LON_kw="4.418" LAT_kw="51.205" /> 

我是 XSL/HTML/JAVASCRIPT 的新手,所以如果你知道答案,请帮助我,提供一些额外的信息(如果你能提供的话)。

【问题讨论】:

  • 您能否展示更多的 XSLT 而不是仅仅在中间截断它(特别是匹配 rows 的模板和 xsl:apply-templates 之后的 javascript )。此外,显示您的输入 XML 可能会有所帮助。谢谢!

标签: javascript html xml xslt


【解决方案1】:

首先你需要替换这一行

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyB1tbIAqN0XqcgTR1-FxYoVTVq6Is6lD98&sensor=false"></script>

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyB1tbIAqN0XqcgTR1-FxYoVTVq6Is6lD98&amp;sensor=false"></script>

特别注意&amp;amp; 需要转义为&amp;amp;

关于让您的 javascript 在构建后工作,您可以手动转义所有有问题的字符。在您的情况下,这意味着替换此行

for (i = 0; i < locations.length; i++)

用这条线

for (i = 0; i &lt; locations.length; i++)

这是为了阻止 XML 解析器将 &lt; 视为标记的开始。

或者,您可以将文本包装为 CDATA,但您需要在两个地方执行此操作。 xsl:apply-templates 之前和之后。例如,您可以这样做

<script type="text/javascript">
  <![CDATA[
    var infos = [];
    var locations = [
  ]]>
  <xsl:apply-templates select='//rows'/>
  <![CDATA[
    ];
    function initialize() {
    }
  ]]>
 </script>

【讨论】:

  • 如果我在脚本中更改有问题的字符,则 不会被识别为 XSL 并且不起作用。为了让应用模板被识别,我必须更改标签脚本周围的 。但这与使用 CDATA 时的结果相同,见下文。我尝试将文本包装为 CDATA,但是当它转换为 html 时,脚本的标签更改为 <和>并且浏览器不知道如何处理它,只是将其显示为文本而不是将其识别为脚本。
猜你喜欢
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 2021-05-05
相关资源
最近更新 更多