【问题标题】:XSLT nested selectsXSLT 嵌套选择
【发布时间】:2014-01-21 04:58:22
【问题描述】:

我对 xslt 比较陌生,我需要根据使用当前帖子的 pid 从哪个帖子中选择 cmets 元素

我遇到问题的 XSLT 部分

<xsl:for-each select="posts/post">
    <div class="post">
        <h3><xsl:value-of select="ptitle"/></h3>
        <span><xsl:value-of select="ptext"/></span>
        <xsl:variable name="pid" select="@pid" />
        <!-- Here i need to select the comment according to the pid -->
    </div>
    <br />
</xsl:for-each>

XML 代码

    <posts>
         <post pid="p2">
            <ptitle>APPLICATIONS OF THE FUTURE</ptitle>
            <pfeatureimage>aig.jpg</pfeatureimage>
            <ptext xml:lang="en">just text </ptext>
            <pdate>25062013</pdate>
            <pimg>future.jpg</pimg>
            <pimg>future.jpg</pimg>
            <pimg>future.jpg</pimg>
            <pauthorid>a3</pauthorid>
        </post>
    </posts>

    <comments>
        <comment cid="c1">
            <pid>p2</pid>
            <uid>u2</uid>
            <ctext>other t</ctext>
            <likes>5</likes>
            <dislikes>1</dislikes>
        </comment>
                <comment cid="c2">
            <pid>p3</pid>
            <uid>u2</uid>
            <ctext>bogsg</ctext>
            <likes>5</likes>
            <dislikes>1</dislikes>
        </comment>
  </comments>

【问题讨论】:

  • 您需要的 XPath 表达式是这样的://comments/comment[pid=current()/@pid]

标签: xml xslt xpath


【解决方案1】:

在 XSLT 中解决此类交叉引用问题的方法是使用key。您将键定义放在样式表的顶层(在任何模板之外):

<xsl:key name="commentsByPid" match="comment" use="pid" />

match 表达式确定要查看哪些节点,use 是相对于每个匹配节点进行评估以确定键值的路径(因此在这种情况下,它将采用 @ 的字符串值每个匹配的 comment 内的 987654326@ 元素)。

通过此键定义,您可以使用key 函数有效地查找与当前帖子的pid 属性匹配的所有cmets:

<xsl:for-each select="posts/post">
    <div class="post">
        <h3><xsl:value-of select="ptitle"/></h3>
        <span><xsl:value-of select="ptext"/></span>
        <xsl:for-each select="key('commentsByPid', @pid)">
            <!-- do whatever you need with the <comment> here -->
        </xsl:for-each>
    </div>
    <br />
</xsl:for-each>

【讨论】:

  • “在 XSLT 中解决此类交叉引用问题的方法是使用密钥” 我也是这么认为的(+1),但显然不是每个人同意:stackoverflow.com/a/21230772/3016153
  • 我更喜欢将键视为优化连接的一种方式,但我对喜欢使用键实现每个连接的人没有任何问题:这是一个合理的选择,它是最好的解决方案大多数时候。
  • @MichaelKay 对我来说,优化的性能是一种奖励;我发现密钥更具可读性和可维护性。但是我可能会偏向于处理关系数据库。
【解决方案2】:

对于单个评论,替换您的变量定义

<xsl:variable name="pid" select="@pid" />

通过

<xsl:value-of select="//comments/comment[pid=current()/@pid]/ctext" />

如果你有多个cmet,你可以试试

<xsl:variable name="pid" select="@pid" />
<xsl:for-each select="//comments/comment[pid=$pid]">
    <xsl:value-of select="ctext" />
</xsl:for-each>

【讨论】:

  • Ian 的回答要好得多。以前不知道。
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2011-05-16
  • 2020-12-07
  • 2019-12-04
  • 1970-01-01
  • 2016-05-22
  • 2011-10-23
相关资源
最近更新 更多