检索一个元素,然后过滤另一个元素 [英] Retrieving one element and filter by another

查看:81
本文介绍了检索一个元素,然后过滤另一个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试并无法从此处修改XSL:不同的元素和分组

Having tried and failed to modify the XSL from here: Distinct elements and grouping

我要在这里发帖询问是否有人可以提供帮助.我基本上拥有与上述文章相同的数据结构(我的实际上是产品的RSS提要),但是我想按排在其中File元素包含特定值的排序顺序唯一地列出Description元素.

I'm posting here to ask if anyone could please help. I've basically got the same data structure (mine is actually an RSS feed of products) as in the above post, but I want to list the Description elements uniquely, in sorted order where the File element contains a particular value.

我相信文件选择的XPath将是:

I believe the XPath for the File select would be:


*/File[text()='file1']

例如,仅采用包含文本"file1"的File元素.

for example, to take only the File elements containing the text "file1".

我无法弄清楚如何获得:已排序的所有不同的Description元素,它们的File兄弟具有值'file1'".

I am unable to work out how to get: "all distinct Description elements sorted, which have a File sibling with value 'file1'".

任何人和所有帮助将不胜感激!

Any and all help will be very, very much appreciated!

谢谢

马特.

推荐答案

XSLT 1.0:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <!-- index Description elements by their text value -->
  <xsl:key name="kDescription" match="Description" use="text()" />

  <xsl:template match="/">
    <output>
      <!-- process all Description elements... -->
      <xsl:apply-templates select="Problems/Problem/Description">
        <!-- ...sorted by their own text value, ascending -->
        <xsl:sort select="text()" />
        <!-- pass in the File value that we want to filter for -->
        <xsl:with-param name="file" select="'file1'" />
      </xsl:apply-templates>
    </output>
  </xsl:template>

  <xsl:template match="Description">
    <xsl:param name="file" select="''" />
    <!-- 
      check if the current Description node is the first in its
      respective group, that has a File value we care for
    -->
    <xsl:if test="
      $file != ''
      and
      generate-id()
      =
      generate-id(key('kDescription', .)[../File = $file][1])
    ">
      <!-- for the sake of simplicity, just make a copy here -->
      <xsl:copy-of select="." />
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

使用此输入:

<Problems>
  <Problem>
    <File>file1</File>
    <Description>desc1</Description>
  </Problem>
  <Problem>
    <File>file1</File>
    <Description>desc2</Description>
  </Problem>
  <Problem>
    <File>file2</File>
    <Description>desc3</Description>
  </Problem>
  <Problem>
    <File>file2</File>
    <Description>desc1</Description>
  </Problem>
  <Problem>
    <File>file1</File>
    <Description>desc2</Description>
  </Problem>
</Problems>    

我得到:

<output>
  <Description>desc1</Description>
  <Description>desc2</Description>
</output>

简要说明样式表中繁重的部分:

A brief explanation of the part of the stylesheet that does the heavy lifting:

$file != ''
and
generate-id()
=
generate-id(key('kDescription', .)[../File = $file][1])

第一部分很明显-只是为了确保传入了$file过滤器字符串.

The first part is obvious - it's just there to make sure that a $file filter string was passed in.

第二部分是简单的Muenchian分组,略有扭曲.它比较两个节点的ID,即当前节点(generate-id())和kDescription组中的一个节点的ID,并按$file值进行过滤.

The second part is plain Muenchian grouping with a little twist. It compares the IDs of two nodes, the current one (generate-id()) and one from the kDescription group, filtered by $file value.

kDescription通过它们的文本值索引<Description>元素,这意味着对key()的调用将返回文本相同但伴随的<File>不同的节点.我们需要将它们过滤掉.

kDescription indexes <Description> elements by their text value, which means that nodes with the same text but a different accompanying <File> will be returned by the call to key(). We need to filter them out.

如果当前节点等于具有正确的<File>值的组中的第一个节点,则测试成功,并且会打印某些内容,否则什么也不会发生.

If the current node is equal to the first node of the group that has the right <File> value, the test succeeds and something gets printed, otherwise nothing happens.

这篇关于检索一个元素,然后过滤另一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆