【问题标题】:Querying an XML file using HTML使用 HTML 查询 XML 文件
【发布时间】:2012-01-20 12:45:00
【问题描述】:

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

我正在尝试创建一个 html 网页,用户可以在其中输入搜索框,例如 'Year < 2009'。它将显示上面找到的表格,但仅显示年份小于 2009 年。

我真的不知道从哪里开始,或者我需要研究什么来创建这个功能。

作为参考,这里有一个 XML sn-p:

<?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>

请注意:我不一定是在寻找代码,或者要写什么,而是,例如,一个向我展示如何实现全部或部分代码的网页

【问题讨论】:

  • 我已添加您的 XML/XLT 以供将来参考。毕竟,您链接到的那个页面可能不会永远存在。

标签: javascript html xml xslt filtering


【解决方案1】:

你可以这样做:

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

<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. 它为每个&lt;th&gt; 添加一个&lt;input&gt; 元素。此输入用作该列的过滤框。
  2. 它维护一组filters,每个列索引一个。
  3. 只要输入更改(当字段失去焦点时发生更改事件),它就会将字段的值写入过滤器集并运行过滤器。
  4. “运行过滤器”是指:
    1. 它遍历每个保存的过滤器字符串,找出使用了哪个运算符(如果有)
    2. 它在受影响的列中查找所有&lt;td&gt; 元素并将它们与过滤器值进行比较。
    3. 当单元格值与过滤器不匹配时,关联的&lt;tr&gt;被隐藏。
    4. 对下一列重复该过程。

此过程会产生附加过滤器,即您可以缩小搜索范围,单独过滤每一列。

过滤字符串的第一个字符应该是操作符。

支持的运算符有

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

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

在 jsFiddle 上查看它的实际效果:http://jsfiddle.net/Tomalak/wjDrr/1/embedded/result/


PS:

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

上面的代码缺乏一些优雅,一旦页面上有超过 一个 表,它就会中断,而且它当然可以针对速度进行优化。如果你在乎,你可以改进这些东西。

【讨论】:

  • 这很棒。我当然必须编辑它,但它很好工作。作为一个对web工作经验0的人,请理解我为什么在这里听起来如此简单:我如何调用这个函数?
  • 您不必自己调用它。页面准备好后,jQuery 会为您执行此操作。试试看。 :)
  • 不可能,这太神奇了。这确实不是我打算创建的,但我会玩得开心。
  • @Dan Trunley:对我来说听起来很接近。您想要创建什么? (或者它是你需要的,而不是你怎么做的?)
  • 不管我怎么做,只要它做到了。我发现这种方法比我预期的要好得多。我打算有一个 html 页面,他们在其中输入搜索字符串,并将其应用于此表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多