![](/img/trans.png)
[英]How to remove elements from xml using xslt with stylesheet and xsltproc?
[英]How to list only unique couples from an XML using XSLT stylesheet?
這是我的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
XSLT 2.0解決方案:
<xsl:for-each-group select="/*/*/author" group-by=".">
<xsl:sort select="current-grouping-key()"/>
<xsl:variable name="firstKey" select="current-grouping-key()"></xsl:variable>
<xsl:for-each-group select="/*/*/author[compare(., current-grouping-key()) = 1][some $x in (current-group()) satisfies $x/parent::* intersect ./parent::*]" group-by=".">
<xsl:value-of select="concat($firstKey, '--',current-grouping-key(),'; ')"></xsl:value-of>
</xsl:for-each-group>
</xsl:for-each-group>
您可以為此使用xslt元素xsl:for-each-group或函數distingle-values()。
在下面的模板中,我將您的序列生成器放在了一個名為round1的變量中,以便可以對其進行處理以刪除重復項。 我更改了內部循環,以創建具有屬性對(與您的配對匹配)和有序版本cannonicalPair的元素(collab)。 對於cannonicalPair來說,是為了消除重復以作者的不同順序進行。 請注意,有時協作的順序在現實世界中很重要。
在round1變量之后是一系列刪除重復項的循環。 前兩個顯示您可以在數據集中輸出協作的任何順序。 如果協作具有不同的順序,則最后一個協作不會將其視為重復。
<xsl:template match="/">
<xsl:variable name="papers" select="dblp/*"/>
<xsl:variable name="round1">
<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:element name="collab">
<xsl:attribute name="pair" select="concat(translate(translate(translate($a1,' ','_'),'.',''),"'",' '), '--', translate(translate(translate(.,' ','_'),'.',''),"'",' '), '; ')"/>
<xsl:attribute name="cannonicalPair">
<xsl:choose>
<xsl:when test="$a1 lt ." >
<xsl:sequence select="concat(translate(translate(translate($a1,' ','_'),'.',''),"'",' '), '--', translate(translate(translate(.,' ','_'),'.',''),"'",' '), '; ')" />
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="concat(translate(translate(translate(.,' ','_'),'.',''),"'",' '), '--', translate(translate(translate($a1,' ','_'),'.',''),"'",' '), '; ')" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:text>
</xsl:text>
<xsl:for-each-group select="$round1/collab" group-by="@cannonicalPair">
<xsl:value-of select="current-group()[1]/@pair" />
</xsl:for-each-group>
<xsl:text>---- listing seperator ----
</xsl:text>
<xsl:for-each-group select="$round1/collab" group-by="@cannonicalPair">
<xsl:value-of select="current-group()[last()]/@pair" />
</xsl:for-each-group>
<xsl:text>---- listing seperator ----
</xsl:text>
<xsl:for-each select="distinct-values($round1/collab/@cannonicalPair)">
<xsl:value-of select="." />
</xsl:for-each>
<xsl:text>---- listing seperator ----
</xsl:text>
<xsl:for-each select="distinct-values($round1/collab/@pair)">
<xsl:value-of select="." />
</xsl:for-each>
此XSLT 2.0轉換:完整,簡短和格式正確 (27行):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kAuthorBySibling" match="author"
use="preceding-sibling::author | following-sibling::author"/>
<xsl:variable name="vAuthors" as="element()*">
<xsl:for-each select="distinct-values(/*/*/author)">
<xsl:sort/>
<a><xsl:value-of select="."/></a>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<xsl:sequence select=
"for $a1 in $vAuthors,
$doc in /,
$a2 in $vAuthors
[. gt $a1
and
. = key('kAuthorBySibling', $a1, $doc)
]
return ($a1/string(), $a2/string(), '
')
"/>
</xsl:template>
</xsl:stylesheet>
當應用於提供的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>
產生想要的正確結果 :
author1 author2
author1 author3
author1 author4
author1 author5
author2 author3
author2 author5
說明 :
變量$vAuthors
是序列a
元素,其組字符串值是集合的不同值的author
在XML文檔中的元素。 a
元素按此順序排序。
關鍵字'kAuthorBySibling'
通過其任何同級(的字符串值)來標識任何“ author”元素。
對於每一個$a1
在$vAuthors
我們得到任何$a2
在$vAuthors
與字符串值高於更大$a1
並使得author
與字符串值相等的元素$a2
是的兄弟author
元素用字符串值相等到$a1
。 為此,我們只需檢查(使用一般相等運算符) $a2
的字符串值是否在key('kAuthorBySibling', $a1, $doc)
的字符串值key('kAuthorBySibling', $a1, $doc)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.