簡體   English   中英

如何使用XSLT樣式表僅列出XML中的唯一對?

[英]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,' ','_'),'.',''),&quot;'&quot;,' '), '--', translate(translate(translate(.,' ','_'),'.',''),&quot;'&quot;,' '), ';&#10;')"/>
                </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(),';&#10;')"></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,' ','_'),'.',''),&quot;'&quot;,' '), '--', translate(translate(translate(.,' ','_'),'.',''),&quot;'&quot;,' '), ';&#10;')"/> 
                      <xsl:attribute name="cannonicalPair">
                        <xsl:choose>
                          <xsl:when test="$a1 lt ." >
                            <xsl:sequence select="concat(translate(translate(translate($a1,' ','_'),'.',''),&quot;'&quot;,' '), '--', translate(translate(translate(.,' ','_'),'.',''),&quot;'&quot;,' '), ';&#10;')" />
                          </xsl:when>
                          <xsl:otherwise>
                            <xsl:sequence select="concat(translate(translate(translate(.,' ','_'),'.',''),&quot;'&quot;,' '), '--', translate(translate(translate($a1,' ','_'),'.',''),&quot;'&quot;,' '), ';&#10;')" />
                          </xsl:otherwise>
                        </xsl:choose>
                      </xsl:attribute>  
                    </xsl:element>
                </xsl:for-each> 
            </xsl:for-each> 
        </xsl:for-each> 
</xsl:variable>

<xsl:text>&#x0A;</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 ----&#x0A;</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 ----&#x0A;</xsl:text>

<xsl:for-each select="distinct-values($round1/collab/@cannonicalPair)">
  <xsl:value-of select="." />
</xsl:for-each>

<xsl:text>---- listing seperator ----&#x0A;</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(), '&#xA;')
      "/>
 </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 

說明

  1. 變量$vAuthors是序列a元素,其組字符串值是集合的不同值的author在XML文檔中的元素。 a元素按此順序排序。

  2. 關鍵字'kAuthorBySibling'通過其任何同級(的字符串值)來標識任何“ author”元素。

  3. 對於每一個$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM