【问题标题】:How to pass parameter to XSLT from Javascript function如何从 Javascript 函数将参数传递给 XSLT
【发布时间】:2015-05-21 09:05:28
【问题描述】:

我浏览了许多试图解释如何实现这一目标的帖子,但没有一个可以帮助我解决问题。

我有一个 HTML 文件,其中包含一个 XML 解析 JavaScript 函数,该函数反过来呈现 XSLT 文件。问题是,我的 XML 文件中有多个“记录”,我只想要一个 XSLT 来呈现每条记录(而不是每条记录一个单独的 XSLT 文件)。根据下面的代码,请有人建议我如何从 JavaScript 传递一个包含记录 ID 的参数(在我的 XML 文件中的每个 XML 记录中),以便“单个”XSLT 可以使用来自的正确数据解析布局参数。

HTML

<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no" />
      <title>Weather App</title>

      <link href="../../css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection" />
      <link href="../../css/animate.css" type="text/css" rel="stylesheet" />
      <link href="../../css/style.css" type="text/css" rel="stylesheet" media="screen,projection" />
    </head>

    <body>

      <div id="WeatherDetailsContainer"></div>

      <!--  Scripts-->
      <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
      <script src="../../js/materialize.js"></script>

      <script>

        $(function(){
          RenderXSLT();
        });

        function loadXMLDoc(filename) {
          if (window.ActiveXObject) {
            xhttp = new ActiveXObject("Msxml2.XMLHTTP");
          } else {
            xhttp = new XMLHttpRequest();
          }
          xhttp.open("GET", filename, false);
          try {
            xhttp.responseType = "msxml-document"
          } catch (err) {} // Helping IE11
          xhttp.send("");
          return xhttp.responseXML;
        }

        function RenderXSLT() {
          xml = loadXMLDoc("datastore/Weather.xml");
          xslt = loadXMLDoc("transformations/WeatherDetailsCard.xslt");
          var currentLocation = localStorage.getItem('current_weather_location');

          if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
            ex = xml.transformNode(xslt);
            document.getElementById("WeatherDetailsContainer").innerHTML = ex;
          }
          else if (document.implementation && document.implementation.createDocument) {
            xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xslt);

            /** I believe this is how to set the param, but it didn't work **/
            //xsltProcessor.setParameter(null, "cityname", currentLocation);

            resultDocument = xsltProcessor.transformToFragment(xml, document);
            document.getElementById("WeatherDetailsContainer").appendChild(resultDocument);
          }
        }
      </script>

    </body>
    </html>

XML 文件

<?xml version="1.0" encoding="UTF-8" ?>
<locations>

  <location>
    <cityid>Lon</cityid>
    <cityname>London</cityname>
    <temperature>11</temperature>
    <high>13</high>
    <low>4</low>
    <date>17/03/2015</date>
  </location>

  <location>
    <cityid>Man</cityid>
    <cityname>Manchester</cityname>
    <temperature>07</temperature>
    <high>08</high>
    <low>2</low>
    <date>17/03/2015</date>
  </location>

  <location>
    <cityid>Gla</cityid>
    <cityname>Glasgow</cityname>
    <temperature>05</temperature>
    <high>06</high>
    <low>1</low>
    <date>17/03/2015</date>
  </location>

</locations>

XSLT 文件

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">

    <!-- How do I use the value of the parameter sent via JavaScript for the cityname (in place of value 'London') -->
    <xsl:for-each select="locations/location[cityname='London']">

      <div class="section">
        <div class="container">
          <div class="row">
            <div class="col s4 m4 l4">
              <div class="card-panel z-depth-3 animated fadeInUp" style="padding:10px 10px 5px 10px !important;">
                <span class="center-align">
                  <h5><xsl:value-of select="cityname"/></h5><span> (<xsl:value-of select="cityid"/>)</span>
                </span>
                <p>Temp: <xsl:value-of select="temperature"/></p>
                <p>High: <xsl:value-of select="high"/></p>
                <p>Low: <xsl:value-of select="low"/></p>                
              </div>
            </div>
          </div>
        </div>
      </div>

    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

【问题讨论】:

    标签: javascript html xml xslt xml-parsing


    【解决方案1】:

    在 XSLT 中你需要改变

    <xsl:template match="/">
    
        <!-- How do I use the value of the parameter sent via JavaScript for the cityname (in place of value 'London') -->
        <xsl:for-each select="locations/location[cityname='London']">
    

    <xsl:param name="cityname"/>
    
    <xsl:template match="/">
    
        <!-- How do I use the value of the parameter sent via JavaScript for the cityname (in place of value 'London') -->
        <xsl:for-each select="locations/location[cityname = $cityname]">
    

    我还会设置 &lt;xsl:output method="html"/&gt;,因为您只是创建 HTML 的片段,而 XSLT 处理器不知道如果您不设置输出方法。

    在您的 Mozilla、Chrome、Opera 的 Javascript 代码中,我会更改检查

          else if (document.implementation && document.implementation.createDocument) {
            xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xslt);
    
            /** I believe this is how to set the param, but it didn't work **/
            //xsltProcessor.setParameter(null, "cityname", currentLocation);
    
            resultDocument = xsltProcessor.transformToFragment(xml, document);
            document.getElementById("WeatherDetailsContainer").appendChild(resultDocument);
          }
    

          else if (typeof XSLTProcessor !== 'undefined') {
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xslt);
    
    
            xsltProcessor.setParameter(null, "cityname", currentLocation);
    
            var resultFragment = xsltProcessor.transformToFragment(xml, document);
            document.getElementById("WeatherDetailsContainer").appendChild(resultFragment);
          }
    

    你的IE代码transformNode不允许设置参数,你也需要改变那部分,改变

          if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
            ex = xml.transformNode(xslt);
            document.getElementById("WeatherDetailsContainer").innerHTML = ex;
          }
    

          if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
            var template = new ActiveXObject('Msxml2.XslTemplate');
            template.stylesheet = xslt;
            var proc = template.createProcessor();
            proc.input = xml;
            proc.addParameter('cityname', currentLocation);
            proc.transform();
            document.getElementById("WeatherDetailsContainer").innerHTML = proc.output;
          }
    

    【讨论】:

      【解决方案2】:

      看起来您的 Javascript 中有正确的代码来传递参数,但您的 XSLT 也必须编写为接受参数:

      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <!-- Declare it here -->
        <xsl:param name="cityName" />
      
        <xsl:template match="/">
          <!--                                 use it here ------v   -->
          <xsl:for-each select="locations/location[cityname = $cityName]">
      
            ...
      
          </xsl:for-each>
        </xsl:template>
      </xsl:stylesheet>
      

      【讨论】:

        猜你喜欢
        • 2012-01-18
        • 1970-01-01
        • 2011-10-02
        • 2016-01-16
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 2012-04-11
        相关资源
        最近更新 更多