我有一些像这样简单的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。
感谢您的所有回复。一些评论和澄清:
此时避免jQuery等人的原因是...... a)这个项目已经有很多其他的依赖关系,我试图限制那个老鼠窝的增长。 b)我倾向于采用自下而上的方法更有效地学习新东西。当我理解较低级别的原子操作时,我觉得使用高级库为我做的工作更加舒服。
有问题的表格非常小而且简单。因此,我倾向于在每次更新时从头开始重新创建整个表。实际上没有必要处理选择性更新的复杂性。
Dimitre:你的XSL看起来很迷人,我肯定会花一些时间来消化它。但是,我不明白(根本)是如何调用此更新。即如何从JavaScript中触发此重新转换?
答案 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>