即时重新填充HTML表格

时间:2010-11-26 16:02:02

标签: javascript xml json xslt xmlhttprequest

我有一些像这样简单的XML:

<Tag>
<Keyphrases>
<Keyphrase Phrase = "This is phrase one"/>
<Keyphrase Phrase = "This is phrase two"/>
<Keyphrase Phrase = "This is phrase three"/>
</Keyphrases>
</Tag>

我有一个包含以下内容的XSLT:

[...]

<table id="realtimetable">
<xsl:apply-templates select="Tag/Keyphrases"/>
</table>

[...]

<!-- Build KeyPhrase Rows -->
<xsl:template match="Tag/Keyphrases">
<xsl:for-each select="Keyphrase">
<tr><td>
<xsl:value-of select="@Phrase" />
</td></tr>
</xsl:for-each>
</xsl:template>

但现在我希望动态更新该表的内容。我知道我可以使用XMLHttpRequest()来获取新数据。

但是,我不知道这些更新使用什么格式或如何将新数据插入表中。

我可以用XML提供更新。但是,我可以重用现有的XSLT模板来解析它并重新填充显示的表吗?这看起来优雅而整洁但是有可能,如果是这样,我该怎么办?

如果那是不可能的,我想我可以编写Javascript来解析XML并自己更新表。这听起来像是很多笨拙的工作: - (

所以我也在考虑以JSON格式响应XMLHTTPRequest。我认为处理JSON可能更容易解析XML。

但是我的JSON文档应该是什么样的,我如何编写JavaScript来处理JSON并重新填充表?

Asumming我有一个来自XMLHttpRequest()的干净(错误检查)响应,我该怎么办?

function ProcessUpdate() 
{
}

我宁愿避免在这个项目中使用任何库,例如jQuery。

更新

感谢您的所有回复。一些评论和澄清:

  1. 此时避免jQuery等人的原因是...... a)这个项目已经有很多其他的依赖关系,我试图限制那个老鼠窝的增长。 b)我倾向于采用自下而上的方法更有效地学习新东西。当我理解较低级别的原子操作时,我觉得使用高级库为我做的工作更加舒服。

  2. 有问题的表格非常小​​而且简单。因此,我倾向于在每次更新时从头开始重新创建整个表。实际上没有必要处理选择性更新的复杂性。

  3. Dimitre:你的XSL看起来很迷人,我肯定会花一些时间来消化它。但是,我不明白(根本)是如何调用此更新。即如何从JavaScript中触发此重新转换?

3 个答案:

答案 0 :(得分:1)

我强烈建议您使用JSON而不是XML来完成此任务 - 正如您已经意识到的那样,您可能不希望在客户端进行XML解析。

将XHR响应作为JSON数据后,您可以使用客户端模板将响应转换为标记,然后将标记放在页面上。如果你改变了对jQuery的看法,那么jQuery有一个模板插件(jQuery.tmpl)可以用来实现这个目的;还有独立的mustache.js和非常轻量级的underscore.js。您当然也可以编写自己的模板代码。所有客户端模板工具都遵循相同的一般原则(尽管语法不同,因此请务必阅读文档),采用如下模板:

<p>Hello, my name is ${firstName} ${lastName}</p>

...然后获取一些数据,例如:

{ "firstName" : "Rebecca", "lastName" : "Murphey" }

...然后将它们组合起来创建所需的输出,然后可以将其添加到DOM中。

如果您尝试更新现有表,则可以为完整表生成HTML,然后删除旧表并插入新表。或者,您可以添加新行 - 这取决于您尝试执行的操作的确切性质。

最后:正如评论者所说,我会重新考虑你反对使用任何类型的图书馆,除非有真正令人信服的理由不这样做。重新发明轮子没有荣耀。

答案 1 :(得分:0)

如果你愿意的话,你可以看看我在我的库中如何做,this函数调用this可爱的函数集来处理JSON。并且this函数用于进行AJAX调用,我已经完成了很多的跨浏览器兼容性研究,因此它就是一个很好的例子。

如果您使用的是PHP,那么您可以将数据编码为JSON并将其传递给JS,如下所示:

echo json_encode($myData);

我认为这不是你的问题,但我确实认为这有助于你更接近。

答案 2 :(得分:0)

这是一个XSLT转换,其中更新被接受为外部参数。它作为源XML文档

在当前表上运行
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pReps">
  <updates>
   <replace line="2">This is new phrase two</replace>
   <delete line="3"/>
   <insert-before line="1">This is phrase zero (new)</insert-before>
   <insert-after line="4">This is phrase five (new)</insert-after>
  </updates>
 </xsl:param>

 <xsl:variable name="vReps"
      select="ext:node-set($pReps)/*/*"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>
   <xsl:apply-templates select="node()"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="tr">
  <xsl:choose>
   <xsl:when test="not(position()=$vReps/@line)">
    <xsl:call-template name="identity"/>
   </xsl:when>
   <xsl:otherwise>
     <xsl:variable name="vPos" select="position()"/>
     <xsl:variable name="vupdCommand"
          select="$vReps[@line=$vPos]"/>
     <xsl:choose>
       <xsl:when test="$vupdCommand[self::replace]">
        <tr><td><xsl:value-of select="$vupdCommand"/></td></tr>
       </xsl:when>
       <xsl:when test="$vupdCommand[self::insert-before]">
        <tr><td><xsl:value-of select="$vupdCommand"/></td></tr>
        <xsl:call-template name="identity"/>
       </xsl:when>
       <xsl:when test="$vupdCommand[self::insert-after]">
        <xsl:call-template name="identity"/>
        <tr><td><xsl:value-of select="$vupdCommand"/></td></tr>
       </xsl:when>
     </xsl:choose>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

在当前表格上应用此转换时

<tabe id="realtimetable">
 <tr><td>This is phrase one</td></tr>
 <tr><td>This is phrase two</td></tr>
 <tr><td>This is phrase three</td></tr>
 <tr><td>This is phrase four</td></tr>
</tabe>

产生了想要的正确结果

<tabe id="realtimetable">
   <tr>
      <td>This is phrase zero (new)</td>
   </tr>
   <tr>
      <td>This is phrase one</td>
   </tr>
   <tr>
      <td>This is new phrase two</td>
   </tr>
   <tr>
      <td>This is phrase four</td>
   </tr>
   <tr>
      <td>This is phrase five (new)</td>
   </tr>
</tabe>