none
XSL 参数与 js 脚本交互的问题 RRS feed

  • 问题

  • filter.xml

    <?xml-stylesheet type="text/xsl" href="filter.xsl"?>
    <root>
      <group name="group1">
        <item id="1">item 1</item>
        <item id="2">item 2</item>
      </group>
      <group name="group2">
        <item id="1">item a</item>
        <item id="2">item b</item>
      </group>
    </root>

    有如上的 xml, 准备写一个 xls 做解析, 要求在展示的结果中, 有一个 group 的选择列表, 可以通过这个选择列表即时过滤显示的 xml  数据

    2012年8月29日 7:35

答案

  • 自己搞定了,实现该功能的 xsl文件如下

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
      <xsl:template match="/">
        <html>
          <head>
            <meta content="text/html" http-equiv="Content-Type"></meta>
            <script language="javascript" name="Filter">
              <![CDATA[
    function filter_group(sName) {
        var iXml = document.XMLDocument;
        var iXsl = document.XSLDocument;
        
        var iPara = iXsl.selectSingleNode('//xsl:param[@name="GroupName"]/@select');
        iPara.value = "'" + sName + "'";
        var iHtml = iXml.documentElement.transformNode(iXsl);
        Layer_Display.innerHTML = iHtml;
    }
    ]]>
            </script>
          </head>
          <body>
            <table>
              <tr>
                <td>
                  <form style="BORDER: 0">
                    <select id="frm_Server">
                      <option value=""><![CDATA[<- Please Select ->]]></option>
                      <xsl:for-each select ="root/group/@name">
                        <xsl:sort select ="."/>
                        <option>
                          <xsl:attribute name ="value">
                            <xsl:value-of select="."/>
                          </xsl:attribute>
                          <xsl:if test="position() =1">
                            <xsl:attribute name ="selected">1</xsl:attribute>
                          </xsl:if>
                          <xsl:value-of select="."/>
                        </option>
                      </xsl:for-each>
                      <option value="*"><![CDATA[<- ALL ->]]></option>
                    </select>
                    <button onClick="filter_group(this.form.frm_Server.value)">Query</button>
                  </form>
                </td>
              </tr>
              <tr>
                <td>
                  <div id="Layer_Display">
                    <xsl:apply-templates select="root"/>
                  </div>
                </td>
              </tr>
            </table>
          </body>
        </html>
      </xsl:template>
      <xsl:template match="root">
        <xsl:param name="GroupName" select ="(group/@name)[1]"/>
        <xsl:apply-templates select="group[@name=$GroupName or $GroupName = '*']"/>
      </xsl:template>
      
      <xsl:template match="group">
        <table>
          <thead>
            <tr>
              <th>id</th>
              <th>value</th>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each select="item">
              <tr>
                <td>
                  <xsl:value-of select="@id"/>
                </td>
                <td>
                  <xsl:value-of select="."/>
                </td>
              </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </xsl:template>
    </xsl:stylesheet>

    2012年9月6日 5:11

全部回复

  • 根据网上搜索的结果, 自己写出了下面的 xls, 但没有达到效果

    filter.xsl

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
      <xsl:template match="/root">
        <xsl:param name="GroupName" select ="(group/@name)[1]"/>
        <html>
          <head>
            <meta content="text/html" http-equiv="Content-Type"></meta>
            <script language="javascript" name="Filter">
              <![CDATA[
    function filter_group(sName) {
        var iXml = document.XMLDocument;
        var iXsl = document.XSLDocument;
        //iXsl.addParameter("GroupName", sName);  //
        var iPara = iXsl.selectSingleNode('//xsl:param[@name="GroupName"]');
        alert(iPara.text);
        var iHtml = iXml.transformNode(iXsl);
        document.write(iHtml);
    }
    ]]>
            </script>
          </head>
          <body>
            <table>
              <tr>
                <td>
                  <form style="BORDER: 0">
                    <select id="frm_Server">
                      <option value="" selected="1"><![CDATA[<- Please Select ->]]></option>
                      <xsl:for-each select ="group/@name">
                        <xsl:sort select ="."/>
                        <option>
                          <xsl:attribute name ="value">
                            <xsl:value-of select="."/>
                          </xsl:attribute>
                          <xsl:value-of select="."/>
                        </option>
                      </xsl:for-each>
                      <option value="*"><![CDATA[<- ALL ->]]></option>
                    </select>
                    <button onClick="filter_group(this.form.frm_Server.value)">Query</button>
                  </form>
                </td>
              </tr>
              <tr>
                <td>
                  <xsl:apply-templates select="group[@name=$GroupName or $GroupName = '*']"/>
                </td>
              </tr>
            </table>
          </body>
        </html>
      </xsl:template>
      <xsl:template match="group">
        <table>
          <thead>
            <tr>
              <th>id</th>
              <th>value</th>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each select="item">
              <tr>
                <td>
                  <xsl:value-of select="@id"/>
                </td>
                <td>
                  <xsl:value-of select="."/>
                </td>
              </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </xsl:template>
    </xsl:stylesheet>

    2012年8月29日 7:37
  • 我的方法, 主要的问题在 js 部分
    1. 不知道如何设置参数值
    2. 通过 transformNode 处理之后 , 第2次再执行这段脚本, 就会出错

    function filter_group(sName) {
      var iXml = document.XMLDocument;
      var iXsl = document.XSLDocument;
      //iXsl.addParameter("GroupName", sName); //网上索引到这种设置参数, 提示没有这个方法
      var iPara = iXsl.selectSingleNode('//xsl:param[@name="GroupName"]');
      alert(iPara.text); // 这个可以找到参数节点, 但不辞谢如何赋值(不知道用那个属性
      var iHtml = iXml.transformNode(iXsl);
      document.write(iHtml); // 这个处理之后, 再次点 button 支持这段脚本, 就会出错
    }

    请教可行的方法
    2012年8月29日 7:39
  • 你好:)

    >>alert(iPara.text); // 这个可以找到参数节点, 但不辞谢如何赋值(不知道用那个属性
    尝试使用innerHtml;

    >>document.write(iHtml); // 这个处理之后, 再次点 button 支持这段脚本, 就会出错
    何错误?

    2012年8月31日 2:09
  • innerhtml /innertext 都试过了, 一样不对, alert 的结果是 undefinied

    document.write(iHtml); 之后的错误信息是 Message: 'undefined' is null or not an object

    猜测的原因是这个之后, 已经是纯粹的 html 内容了(因为前面有 transformNode, 所以下面这个已经取不到对象

      var iXml = document.XMLDocument;
     
    var iXsl = document.XSLDocument;

    2012年8月31日 7:21
  • 你好:)

    如果你比较着急,不妨尝试这个方法:

    1)把选项绑定到Dropdownlist中。并且设置Dropdownlist的AutoPostBack=true。

    2)随后双击该Dropdownlist,然后直接使用 XmlDocument的SelectNodes方法输出xml的字符串,赋值到label或者其它地方。


    2012年8月31日 8:27
  • 没看明白, 你描述的到底是用的什么技术或者工具, 我已经给出了 xml 和 xsl, 如果你的方法确实可行, 请帮忙写出可行的 xsl 代码吧
    2012年9月6日 1:32
  • 没看明白, 你描述的到底是用的什么技术或者工具, 我已经给出了 xml 和 xsl, 如果你的方法确实可行, 请帮忙写出可行的 xsl 代码吧

    哦,我没有用xsl,而是采用下拉列表选项的SelectIndexChanged事件+XmlDocument的方式进行数据过滤的。
    2012年9月6日 1:43
  • XmlDocument 是从那里装载数据呢?是 Load 一个文件么?
    2012年9月6日 1:51
  • XmlDocument 是从那里装载数据呢?是 Load 一个文件么?

    是的,使用Load方法。或者直接通过LoadXml直接加载一个xml格式的String。
    2012年9月6日 1:54
  • 其实我主要就是不想去 oad 文件

    Load文件,意味着我需要在脚本中去指定 xml 文件名,这样有多个 xml 文件需要用同一个 xsl 解析时,我需要去改 xsl 文件,以后有更多的 xml 文件要用这个 xsl 时,也比较麻烦

    而不 Load 文件的话,我只需要在 xml 头部加一个 href="filter.xsl"? 就行了(xsl 和 xml 是一对多的关系)

    2012年9月6日 2:04
  • 自己搞定了,实现该功能的 xsl文件如下

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
      <xsl:template match="/">
        <html>
          <head>
            <meta content="text/html" http-equiv="Content-Type"></meta>
            <script language="javascript" name="Filter">
              <![CDATA[
    function filter_group(sName) {
        var iXml = document.XMLDocument;
        var iXsl = document.XSLDocument;
        
        var iPara = iXsl.selectSingleNode('//xsl:param[@name="GroupName"]/@select');
        iPara.value = "'" + sName + "'";
        var iHtml = iXml.documentElement.transformNode(iXsl);
        Layer_Display.innerHTML = iHtml;
    }
    ]]>
            </script>
          </head>
          <body>
            <table>
              <tr>
                <td>
                  <form style="BORDER: 0">
                    <select id="frm_Server">
                      <option value=""><![CDATA[<- Please Select ->]]></option>
                      <xsl:for-each select ="root/group/@name">
                        <xsl:sort select ="."/>
                        <option>
                          <xsl:attribute name ="value">
                            <xsl:value-of select="."/>
                          </xsl:attribute>
                          <xsl:if test="position() =1">
                            <xsl:attribute name ="selected">1</xsl:attribute>
                          </xsl:if>
                          <xsl:value-of select="."/>
                        </option>
                      </xsl:for-each>
                      <option value="*"><![CDATA[<- ALL ->]]></option>
                    </select>
                    <button onClick="filter_group(this.form.frm_Server.value)">Query</button>
                  </form>
                </td>
              </tr>
              <tr>
                <td>
                  <div id="Layer_Display">
                    <xsl:apply-templates select="root"/>
                  </div>
                </td>
              </tr>
            </table>
          </body>
        </html>
      </xsl:template>
      <xsl:template match="root">
        <xsl:param name="GroupName" select ="(group/@name)[1]"/>
        <xsl:apply-templates select="group[@name=$GroupName or $GroupName = '*']"/>
      </xsl:template>
      
      <xsl:template match="group">
        <table>
          <thead>
            <tr>
              <th>id</th>
              <th>value</th>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each select="item">
              <tr>
                <td>
                  <xsl:value-of select="@id"/>
                </td>
                <td>
                  <xsl:value-of select="."/>
                </td>
              </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </xsl:template>
    </xsl:stylesheet>

    2012年9月6日 5:11