检索一个元素,然后过滤另一个元素 [英] Retrieving one element and filter by another
问题描述
尝试并无法从此处修改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屋!