XSLT注释系统



我正在尝试用XSLT构建一个注释系统。以下是已提交评论的XML输入:

<in:inputs xmlns:in="http://www.composite.net/ns/transformation/input/1.0">
<!-- Input Parameter, XPath /in:inputs/in:param[@name='story_id'] -->
<in:param name="story_id">182485599</in:param>
<!-- Function Call Result (0 ms), XPath /in:inputs/in:result[@name='LoggedInWebUserID'] -->
<in:result name="LoggedInWebUserID">233459</in:result>
<!-- Function Call Result (9 ms), XPath /in:inputs/in:result[@name='XML_Comment']/root -->
<in:result name="XML_Comment">
    <root xmlns="">
        <Comments CommentID="1" ResponseCommentID="0" WebUserID="123456" FULL_NAME="Osikhuemhe Abulume" Comment="test comment!!!!" DateSubmitted="Feb 20 2013  1:34PM"/>
        <Comments CommentID="2" ResponseCommentID="0" WebUserID="261337" FULL_NAME="Phillip Lowe" Comment="test comment2!!!!" DateSubmitted="Feb 20 2013  5:14PM"/>
        <Comments CommentID="3" ResponseCommentID="1" WebUserID="000007" FULL_NAME="Norman Abbott" Comment="my response" DateSubmitted="Feb 20 2013  5:14PM"/>
        <Comments CommentID="4" ResponseCommentID="0" WebUserID="233459" FULL_NAME="Tamara Failor" Comment="Not impressed..." DateSubmitted="Feb 20 2013  4:10PM"/>
        <Comments CommentID="5" ResponseCommentID="0" WebUserID="233459" FULL_NAME="Tamara Failor" Comment="blah blah blah. " DateSubmitted="Feb 20 2013  4:11PM"/>
        <Comments CommentID="6" ResponseCommentID="0" WebUserID="233459" FULL_NAME="Tamara Failor" Comment="dfsfs" DateSubmitted="Feb 20 2013  4:14PM"/>
        <Comments CommentID="7" ResponseCommentID="5" WebUserID="233459" FULL_NAME="Tamara Failor" Comment="this is a response to blah blah blah." DateSubmitted="Feb 20 2013  4:52PM"/>
        <Comments CommentID="8" ResponseCommentID="3"  WebUserID="233459" FULL_NAME="Tamara Failor" Comment="I don't agree with Norman. Terrible response." DateSubmitted="Feb 20 2013  5:39PM"/>
        <Comments CommentID="9" ResponseCommentID="4"  WebUserID="233459" FULL_NAME="Tamara Failor" Comment="I'm impressed." DateSubmitted="Feb 20 2013  5:43PM"/>
        <Comments CommentID="10" ResponseCommentID="1" WebUserID="233459" FULL_NAME="Tamara Failor" Comment="I've got something to say!" DateSubmitted="Feb 20 2013  6:34PM"/>
    </root>
</in:result>

这应该像任何其他新闻报道的评论系统一样工作(请参阅:http://www.npr.org/2013/02/20/172384724/when-a-bad-economy-means-working-forever)

也就是说,新的评论(ResponseCommentID=0)总是被推到左边。

对这些评论的回应将缩进在下面。(我现在不在乎缩进。我想得到评论的回复,让它们相互叠加)

有两个部分我被卡住了。第一部分是每个帖子应该如何命名:

    <xsl:variable name="story_id" select="/in:inputs/in:param[@name='story_id']" />
    <xsl:variable name="root" select="/in:inputs/in:result[@name='XML_Comment']/root" />
    <xsl:for-each select="$root/Comments[@ResponseCommentID=0]">
    <!-- call the template to plot the first comment down -->
        <xsl:call-template name="thecomment">
            <xsl:with-param name="CommentID"><xsl:value-of select="@CommentID" /></xsl:with-param>
            <xsl:with-param name="ResponseCommentID"><xsl:value-of select="@ResponseCommentID" /></xsl:with-param>
        </xsl:call-template>
    <!-- if the comment has any responses, put those underneath the root -->
        <xsl:for-each select="$root/Comments[current()/@CommentID = $root/Comments/@ResponseCommentID]">
            <xsl:call-template name="thecomment">
                <xsl:with-param name="CommentID"><xsl:value-of select="@CommentID" /></xsl:with-param>
                <xsl:with-param name="ResponseCommentID"><xsl:value-of select="@ResponseCommentID" /></xsl:with-param>
            </xsl:call-template>
        </xsl:for-each>

模板的(也是非常错误的)结束递归部分:

    <xsl:if test="@CommentID = $root/Comments/@ResponseCommentID">
       <xsl:call-template name="thecomment">
            <xsl:with-param name="CommentID"><xsl:attribute name="value"><xsl:value-of select="@CommentID[@CommentID = $root/Comments/@ResponseCommentID]" /></xsl:with-param>
            <xsl:with-param name="ResponseCommentID"><xsl:attribute name="value"><xsl:value-of select="@ResponseCommentID[@CommentID = $root/Comments/@ResponseCommentID]" /></xsl:with-param>
        </xsl:call-template>
    </xsl:if>

如果有人能把我推向正确的方向,我将不胜感激。如果需要更多信息,请告诉我。实际的模板"thecomment"只是接受传递给它的注释,并按照我想要的方式对其进行格式化。

您可以考虑将两者合并为一个xsl:apply-templates调用,而不是对每个使用xsl:for-each,然后调用一个命名模板。首先,您将选择ResponseCommentID属性为0的注释。

<xsl:apply-templates 
   select="in:inputs/in:result[@name='XML_Comment']/root/Comments[@ResponseCommentID='0']" />

然后,您将有一个模板来匹配Comments属性,在其中您将输出注释详细信息。然后你可以递归地得到这样的响应注释:

<xsl:apply-templates select="../Comments[@ResponseCommentID = current()/@CommentID]" />

这将只是递归地调用相同的Comments模板,直到不再有响应为止。

以下是本例中的完整XSLT(作为示例,我将注释作为HTML中的列表项输出)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" exclude-result-prefixes="in">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="/">
      <ul>
      <xsl:apply-templates select="in:inputs/in:result[@name='XML_Comment']/root/Comments[@ResponseCommentID='0']" />
      </ul>
   </xsl:template>
      <xsl:template match="Comments">
      <li>
         <xsl:value-of select="@Comment" />
         <xsl:if test="../Comments[@ResponseCommentID = current()/@CommentID]">
            <ul>
               <xsl:apply-templates select="../Comments[@ResponseCommentID = current()/@CommentID]" />
            </ul>
         </xsl:if>
      </li>
   </xsl:template>
</xsl:stylesheet>

这给出了以下输出

<ul>
   <li>test comment!!!!
      <ul>
         <li>my response
            <ul>
               <li>I don't agree with Norman. Terrible response.</li>
            </ul>
         </li>
         <li>I've got something to say!</li>
      </ul>
   </li>
   <li>test comment2!!!!</li>
   <li>Not impressed...
      <ul>
         <li>I'm impressed.</li>
      </ul>
   </li>
   <li>blah blah blah. 
      <ul>
         <li>this is a response to blah blah blah.</li>
      </ul>
   </li>
   <li>dfsfs</li>
</ul>

但是,在此处使用xsl:key来查找对注释的响应会更有效:

<xsl:key name="Comments" match="Comments" use="@ResponseCommentID" />

然后要获得顶级评论,你可以这样做:

<xsl:apply-templates select="key('Comments', '0')" />

为了在匹配模板中获得对给定评论的响应,您可以执行以下

<xsl:apply-templates select="key('Comments', @CommentID)" />

下面的XSLT也给出了相同的结果

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" exclude-result-prefixes="in">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="Comments" match="Comments" use="@ResponseCommentID" />
   <xsl:template match="/">
      <ul>
      <xsl:apply-templates select="key('Comments', '0')" />
      </ul>
   </xsl:template>
      <xsl:template match="Comments">
      <li>
         <xsl:value-of select="@Comment" />
         <xsl:if test="key('Comments', @CommentID)">
            <ul>
               <xsl:apply-templates select="key('Comments', @CommentID)" />
            </ul>
         </xsl:if>
      </li>
   </xsl:template>
</xsl:stylesheet>

我想我想通了。以下是我的XLST现在的样子。它将浏览所有评论,但前提是它是第一篇帖子(@ResponseCommentID=0)。

<xsl:for-each select="$root/Comments">
<xsl:if test="@ResponseCommentID = 0 and @CommentID != $root/Comments/@ResponseCommentID">
    <!-- call the template to first plot the comment down -->
        <xsl:call-template name="thecomment">
            <xsl:with-param name="CommentID"><xsl:value-of select="@CommentID" /></xsl:with-param>
            <xsl:with-param name="ResponseCommentID"><xsl:value-of select="@ResponseCommentID" /></xsl:with-param>
        </xsl:call-template>
</xsl:if>
</xsl:for-each>

这是最后的递归部分。它查看所有注释,并为每个@ResponseCommentID属性调用模板,该属性等于当前的@CommentID。

        <xsl:for-each select="$root/Comments[@ResponseCommentID = current()/@CommentID]">
       <xsl:call-template name="thecomment">
            <xsl:with-param name="CommentID"><xsl:value-of select="@CommentID" /></xsl:with-param>
            <xsl:with-param name="ResponseCommentID"><xsl:value-of select="@ResponseCommentID" /></xsl:with-param>
        </xsl:call-template>
    </xsl:for-each>

仍然不完全理解(我不得不在脑海中回放事件的顺序),但我相信这是有效的。:)

相关内容

  • 没有找到相关文章

最新更新