使用HTML查询XML文件

时间:2011-12-14 18:18:24

标签: javascript html xml xslt filtering

我有一个.xml文件,其中包含.xsl个文件。其输出可以是found here

我正在尝试使用html网页,用户可以在其中输入搜索框,例如'Year < 2009'。它将显示上面的表格,但仅显示年份低于2009年的情况。

我真的不知道从哪里开始,或者我需要考虑创建此功能。

供参考,这是一个XML片段:

<?xml-stylesheet type="text/xsl" href="podcatalog.xsl"?>
<pods-papers>
  <inproceedings key="AbbadiSC85">
    <crossref>conf/pods/85</crossref>
    <author>Amr El Abbadi</author>,
    <author>Dale Skeen</author>,
    <author>Flaviu Cristian</author>,
    <title>An Efficient, Fault-Tolerant Protocol for Replicated Data Management.</title>,
    <pages>215-229</pages>,
    <year>1985</year>,
    <booktitle>PODS</booktitle>,
  </inproceedings>
  <inproceedings key="AbbadiT86">
    <crossref>conf/pods/86</crossref>
    <author>Amr El Abbadi</author>,
    <author>Sam Toueg</author>,
    <title>Availability in Partitioned Replicated Databases.</title>,
    <pages>240-251</pages>,
    <year>1986</year>,
    <booktitle>PODS</booktitle>,
  </inproceedings>
  <inproceedings key="Abdel-GhaffarA90">
    <crossref>conf/pods/90</crossref>
    <author>Khaled A. S. Abdel-Ghaffar</author>,
    <author>Amr El Abbadi</author>,
    <title>On the Optimality of Disk Allocation for Cartesian Product Files.</title>,
    <pages>258-264</pages>,
    <year>1990</year>,
    <booktitle>PODS</booktitle>,
  </inproceedings>
  <inproceedings key="Abiteboul83">
    <crossref>conf/pods/83</crossref>
    <author>Serge Abiteboul</author>,
    <title>Disaggregations in Databases.</title>,
    <pages>384-388</pages>,
    <year>1983</year>,
    <booktitle>PODS</booktitle>,
  </inproceedings>
</pods-papers>

这是XSLT("podcatalog.xsl"):

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>Pods Papers</h2>
  <table border="1">
    <tr bgcolor="#9ACD32">
      <th>Author</th>
      <th>Title</th>
      <th>Pages</th>
      <th>Year</th>
    </tr>
    <xsl:for-each select="pods-papers/inproceedings">
    <xsl:sort select="author"/>
    <tr>
      <td><xsl:value-of select="author"/></td>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="pages"/></td>
      <td><xsl:value-of select="year"/></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

请注意: 我不一定在寻找代码或要写的内容,但是,例如,一个网页向我展示了如何实现全部或部分 < /强>

1 个答案:

答案 0 :(得分:1)

你可以这样做:

向XSLT添加两个脚本元素,这些元素将显示在生成的HTML中。第一个是jQuery(谷歌托管的版本,为方便起见):

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

,第二个操作结果表:

<script type="text/javascript"><![CDATA[
$(function () {
  var filters = {};
  filters.run = function () {
    var i, $th = $("th"), $td, value;

    $("table tr:not(:visible)").show(); // clear any previously hidden rows

    for (var i=0; i<$th.length; i++) {  // for each filter string...
      if (this[i] > "") {
        $td = $th.eq(i).closest("table").find("tr:visible td:nth-child(" + (i+1) + ")");

        switch (this[i].slice(0,1)) { // first character is the operator
          case "<":
            value = $.trim( this[i].slice(1).toLowerCase() );
            $td.filter(function () {
              return $.trim( $(this).text().toLowerCase() ) >= value;
            }).closest("tr:visible").hide();
            break;
          case ">":
            value = $.trim( this[i].slice(1).toLowerCase() );
            $td.filter(function () {
              return $.trim( $(this).text().toLowerCase() ) <= value;
            }).closest("tr:visible").hide();
            break;
          case "/":
            value = new RegExp( this[i].slice(1) );
            $td.filter(function () {
              return !value.test( $.trim( $(this).text() ) );
            }).closest("tr:visible").hide();
            break;
          case "=":
            value = $.trim( this[i].slice(1).toLowerCase() );
            $td.filter(function () {
              return $.trim( $(this).text().toLowerCase() ) != value;
            }).closest("tr:visible").hide();
            break;
          default:
            value = $.trim( this[i].toLowerCase() );
            $td.filter(function () {
              return $.trim( $(this).text().toLowerCase() ).indexOf(value) == -1;
            }).closest("tr:visible").hide();
            break;
        }
      }
    }
  }

  $("th").each(function () {
    $(this).append("<input type='text'>");
  });

  $("th input").change(function () {
    var index = $(this).closest("th").prevAll("th").length;

    filters[index] = $.trim( $(this).val() );
    filters.run();
  });
});
]]></script>

这就是它的作用:

  1. 它为每个<input>添加了<th>个元素。此输入用作该列的过滤器框。
  2. 它维护一组filters,每列索引一个。
  3. 每当输入发生变化时(当字段失去焦点时发生变化事件),它会将字段的值写入过滤器集并运行过滤器。
  4. “运行过滤器”是指:
    1. 通过每个保存的过滤字符串,确定使用了哪个运算符(如果有)
    2. 它会在受影响的列中找到所有<td>个元素,并将它们与过滤器值进行比较。
    3. 当单元格值与过滤器不匹配时,关联的<tr>将被隐藏。
    4. 重复下一栏的流程。
  5. 此过程会产生附加过滤器,即您可以缩小搜索范围,逐个过滤每列。

    过滤字符串的第一个字符应该是运算符。

    支持的运营商

    • <(小于),
    • >(大于)
    • =(完全相等)
    • /(正则表达式)。
    • 任何其他过滤字符串都被解释为“包含”。
    • 如果需要,可添加更多运算符。

    除正则表达式之外的所有比较都不区分大小写。

    在jsFiddle上查看它:http://jsfiddle.net/Tomalak/wjDrr/1/embedded/result/


    P.S。:

    我知道这基本上解决了你的整个问题。你说你不知道从哪里开始,所以我想你将有足够的时间来搞清楚代码并进一步根据你的需要进行调整。 :)

    上面的代码缺乏一些优雅,只要页面上有更多的一个表就会中断,并且它当然可以针对速度进行优化。如果你关心,你可以改善这些。