如何使用 XSLT 样式表仅列出 XML 中的唯一对?
这是我的 XML 结构:
<dblp>
<inproceedings key="aaa" mdate="bbb">
<author>author1</author>
<author>author2</author>
<author>author3</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</inproceedings>
<article key="aaa" mdate="bbb">
<author>author1</author>
<author>author4</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</article>
<article key="aaa" mdate="bbb">
<author>author1</author>
<author>author2</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</article>
<inproceedings key="aaa" mdate="bbb">
<author>author2</author>
<author>author1</author>
<author>author5</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</inproceedings>
</dblp>
我需要显示合作撰写一篇文章(以及正在进行的文章)的所有作者。
因此,我们只需要列出独特的夫妇,以了解哪些作者合作过。 这是我的 XSL,其中列出了所有对,但我需要添加一些代码来过滤选择并删除已列出的对:
<xsl:variable name="papers" select="dblp/*"/>
<xsl:for-each select="$papers">
<xsl:for-each select="author[position() != last()]">
<xsl:variable name="a1" select="."/>
<xsl:for-each select="following-sibling::author">
<xsl:value-of select="concat(translate(translate(translate($a1,' ','_'),'.',''),"'",' '), '--', translate(translate(translate(.,' ','_'),'.',''),"'",' '), '; ')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
当前输出:
author1--auhtor2
author1--auhtor3
author2--auhtor3
author1--auhtor4
author1--auhtor2
author2--auhtor1
author2--auhtor5
author1--auhtor5
输出应如下所示:
author1--auhtor2
author1--auhtor3
author2--auhtor3
author1--auhtor4
---
---
author2--auhtor5
author1--auhtor5
This is my XML structure:
<dblp>
<inproceedings key="aaa" mdate="bbb">
<author>author1</author>
<author>author2</author>
<author>author3</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</inproceedings>
<article key="aaa" mdate="bbb">
<author>author1</author>
<author>author4</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</article>
<article key="aaa" mdate="bbb">
<author>author1</author>
<author>author2</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</article>
<inproceedings key="aaa" mdate="bbb">
<author>author2</author>
<author>author1</author>
<author>author5</author>
<title>Title of pubblications</title>
<pages>12345</pages>
<year>12345</year>
<crossref>sometext</crossref>
<booktitle>sometext</booktitle>
<url>sometext</url>
<ee>sometext</ee>
</inproceedings>
</dblp>
I need to display all couples of authors who have collaborated for an article (and inproceedings).
So we need to list only unique couples, to know wich authors have collaborated.
This is my XSL where I list all couples, but i need to add some code to filter the selection and remove the couples already listed:
<xsl:variable name="papers" select="dblp/*"/>
<xsl:for-each select="$papers">
<xsl:for-each select="author[position() != last()]">
<xsl:variable name="a1" select="."/>
<xsl:for-each select="following-sibling::author">
<xsl:value-of select="concat(translate(translate(translate($a1,' ','_'),'.',''),"'",' '), '--', translate(translate(translate(.,' ','_'),'.',''),"'",' '), ';
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
Current output:
author1--auhtor2
author1--auhtor3
author2--auhtor3
author1--auhtor4
author1--auhtor2
author2--auhtor1
author2--auhtor5
author1--auhtor5
The output should be like this:
author1--auhtor2
author1--auhtor3
author2--auhtor3
author1--auhtor4
---
---
author2--auhtor5
author1--auhtor5
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
XSLT 2.0 解决方案:
An XSLT 2.0 solution :
为此,您可以使用 xslt 元素 xsl:for-each-group 或函数 unique-values()。
在下面的模板中,我将序列生成器放入名为 round1 的变量中,以便可以对其进行处理以删除重复项。我更改了内部循环以创建一个带有属性对(与您的配对匹配)的元素(协作)和一个名为 cannonicalPair 的有序版本。 cannonicalPair 用于消除按不同作者顺序执行的重复操作。请注意,有时协作的顺序在现实世界中很重要。
round1 变量后面是一系列删除重复项的循环。前两个显示您可以输出数据集中协作的任一顺序。如果协作的顺序不同,最后一个不会将协作视为重复。
You can use the xslt element xsl:for-each-group or the function distinct-values() for this.
In the template below I have put your sequence generator in a variable called round1 so it can be processed to remove duplicates. I have changed the inner loop to create an element (collab) with attributes pair (that matches your pairing) and an ordered version called cannonicalPair. To the cannonicalPair is used to eliminate duplicates do to different order of the authors. Note that sometimes the order of a collaboration is significant in the real world.
Following the round1 variable are a series of loops that remove the duplicates. The first two show that you can output either ordering of the collaboration in your data set. The last does not treat collaborations as duplicate if they have different order.
此 XSLT 2.0 转换:完整、简短且格式良好(27 行):
应用于提供的 XML 文档时:
产生所需的正确结果 strong>:
解释:
变量
$vAuthors
是a
元素的序列,其字符串值集是不同值的集中的author
元素XML 文档。a
元素按此顺序排序。键
'kAuthorBySibling'
通过其任何同级元素(的字符串值)标识任何“author”元素。对于
$vAuthors
中的每个$a1
,我们得到$vAuthors
中字符串值大于的任何$a2
比$a1
的元素高,并且字符串值等于$a2
的author
元素是author 的同级元素字符串值等于 的
元素$a1
。为此,我们只需检查(使用一般相等运算符)$a2
的字符串值是否在key('kAuthorBySibling', $a1, $doc)< 的字符串值集中/code>.
This XSLT 2.0 transformation: complete, short and well-formatted (27 lines):
when applied on the provided XML document:
produces the wanted, correct result:
Explanation:
The variable
$vAuthors
is a sequence ofa
elements whose set of string values is the set of distinct values of theauthor
elements in the XML document. Thea
elements are sorted in this sequence.The key
'kAuthorBySibling'
identifies any `author element by (the string value of) any of its siblings.For each
$a1
in$vAuthors
we get any$a2
in$vAuthors
with string value greater than that of$a1
and such that anauthor
element with string value equal to that of$a2
is a sibling of anauthor
element with string value equal to that of$a1
. For this we simply check (using the general equality operator) whether the string value of$a2
is in the set of string values ofkey('kAuthorBySibling', $a1, $doc)
.