Xml 从current-grouping-key()xslt中访问属性

Xml 从current-grouping-key()xslt中访问属性,xml,xslt-2.0,xslt-grouping,Xml,Xslt 2.0,Xslt Grouping,我有一些包含数千个电影元素的xml,它们都可以有一个或多个导演和编剧元素,如果一个导演或编剧与另一个同名,如图所示,如果他们不是同一个人,我会添加一个@differentior of birthyear <mediaList> <movie id="1603934" dateCreated="2014-08-11"> <title>Night at the Museum</title> <

我有一些包含数千个电影元素的xml,它们都可以有一个或多个导演和编剧元素,如果一个导演或编剧与另一个同名,如图所示,如果他们不是同一个人,我会添加一个@differentior of birthyear

<mediaList>
        <movie id="1603934" dateCreated="2014-08-11">
          <title>Night at the Museum</title>
          <director>Shawn Levy</director>
          <LCSpecialTopics>Comedy</LCSpecialTopics>
          <writer>Robert Ben Garant</writer>
          <writer differentiator="1970">Thomas Lennon</writer>
          <language>English</language>
          <year>2006</year>
       </movie>

      <movie lastModified="2014-08-30" id="1123629" dateCreated="2014-08-04">
          <title type="foreign" xml:lang="cmn">Qiúgǎng Wèishì</title>
          <title>Warriors of Qiugang</title>
          <director>Ruby Yang</director>
          <LCSpecialTopics>Documentary films</LCSpecialTopics>
          <writer differentiator="1951">Thomas Lennon</writer>
          <language>Chinese</language>
          <year>2010</year>
       </movie>
</mediaList>
所需的输出(代码段)如下所示:

        <tr>
           <td>Some Number</td>
           <td>
              <p><a id="Thomas Lennon1951">Thomas Lennon (1951)</a></p>
           </td>
           <td>
              <h3>Writer</h3>
              <p>Warriors of Qiugang<span> (Qiúgǎng Wèishì)</span></p>
           </td>
        </tr>
        <tr>
           <td>Some Number</td>
           <td>
              <p><a id="Thomas Lennon1970">Thomas Lennon (1970)</a></p>
           </td>
           <td>
              <h3>Writer</h3>
              <p>Night at the Museum</p>
           </td>
        </tr>

一些数字
托马斯·列侬(1951)

作家 秋港勇士

一些数字 托马斯·列侬(1970)

作家 博物馆之夜


您可以使用
group by=“writer/concat(@differentior,“+”),director”
详细说明Martin给出的简短答案。将
writer
的字符串值和潜在的
微分器
属性连接起来,并将其作为“分组依据”值交给每个组的

然后,两个变量
$person
$year
再次分隔分组键的两个部分。这只解决了
writer
元素的问题,而不是
director
的问题

另请注意,通常ID不能包含空格。如果id属性是“true”id,则应该去掉id值中的任何空白

另外,使用
exclude prefixes=“#all”
防止未使用的名称空间出现在输出HTML中

样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="#all"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:functx="http://www.functx.com" version="2.0">
    <xsl:output method="html" indent="yes"/>

    <xsl:function name="functx:substring-after-last-match" as="xs:string"
        xmlns:functx="http://www.functx.com">
        <xsl:param name="arg" as="xs:string?"/>
        <xsl:param name="regex" as="xs:string"/>

        <xsl:sequence select="
            replace($arg,concat('^.*',$regex),'')
            "/>

    </xsl:function>

    <xsl:template match="mediaList">
        <html>
            <head>
                <link rel="stylesheet" type="text/css" href="CssJs/tableMedia.css"/>
                <title>Media Table</title>
            </head>
            <body>
                <table>
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>Person</th>
                            <th>Movies</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each-group select="movie" group-by="writer/concat(@differentiator, '_', .), director">
                            <xsl:sort
                                select="functx:substring-after-last-match(current-grouping-key(),'\s')"/>
                            <xsl:sort select="current-grouping-key()"/>

                           <xsl:variable name="person" select="if (contains(current-grouping-key(),'_')) then substring-after(current-grouping-key(),'_') else current-grouping-key()"/>
                            <xsl:variable name="year" select="if (contains(current-grouping-key(),'_')) then substring-before(current-grouping-key(),'_') else ''"/>

                            <tr>
                                <td>
                                    <xsl:value-of select="position()"/>
                                </td>
                                <td>
                                    <p>
                                        <a id="{concat(replace($person,' ',''),$year)}">
                                            <xsl:value-of select="if ($year) then concat($person,' (',$year,')') else $person"/>
                                        </a>
                                    </p>
                                </td>
                                <td>
                                    <xsl:if test="current-group()[writer = $person]">
                                        <h3>Writer</h3>
                                    </xsl:if>
                                    <xsl:apply-templates
                                        select="current-group()[writer = $person]/title[not(@type)]"/>
                                    <xsl:if test="current-group()[director = $person]">
                                        <h3>Director</h3>
                                    </xsl:if>
                                    <xsl:apply-templates
                                        select="current-group()[director = $person]/title[not(@type)]"
                                    />
                                </td>
                            </tr>
                        </xsl:for-each-group>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="title">
        <p>
            <xsl:value-of select="."/>
            <xsl:apply-templates select="../title[@type]"/>
        </p>
    </xsl:template>

    <xsl:template match="title[@type]">
        <span>
            <xsl:value-of select="concat(' (',.,')')"/>
        </span>
    </xsl:template>            
</xsl:stylesheet>
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <link rel="stylesheet" type="text/css" href="CssJs/tableMedia.css">
      <title>Media Table</title>
   </head>
   <body>
      <table>
         <thead>
            <tr>
               <th>#</th>
               <th>Person</th>
               <th>Movies</th>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td>1</td>
               <td>
                  <p><a id="FrodoBaggins">Frodo Baggins</a></p>
               </td>
               <td>
                  <h3>Director</h3>
                  <p>Second movie</p>
               </td>
            </tr>
            <tr>
               <td>2</td>
               <td>
                  <p><a id="RobertBenGarant">Robert Ben Garant</a></p>
               </td>
               <td>
                  <h3>Writer</h3>
                  <p>Night at the Museum</p>
               </td>
            </tr>
            <tr>
               <td>3</td>
               <td>
                  <p><a id="ThomasLennon1951">Thomas Lennon (1951)</a></p>
               </td>
               <td>
                  <h3>Writer</h3>
                  <p>Warriors of Qiugang<span> (Qiúgǎng Wèishì)</span></p>
               </td>
            </tr>
            <tr>
               <td>4</td>
               <td>
                  <p><a id="ThomasLennon1970">Thomas Lennon (1970)</a></p>
               </td>
               <td>
                  <h3>Writer</h3>
                  <p>Night at the Museum</p>
                  <p>Second movie</p>
               </td>
            </tr>
            <tr>
               <td>5</td>
               <td>
                  <p><a id="ShawnLevy">Shawn Levy</a></p>
               </td>
               <td>
                  <h3>Director</h3>
                  <p>Night at the Museum</p>
               </td>
            </tr>
            <tr>
               <td>6</td>
               <td>
                  <p><a id="RubyYang">Ruby Yang</a></p>
               </td>
               <td>
                  <h3>Director</h3>
                  <p>Warriors of Qiugang<span> (Qiúgǎng Wèishì)</span></p>
               </td>
            </tr>
         </tbody>
      </table>
   </body>
</html>

媒体表
#
人
影视

经理 第二部电影

2. 罗伯特·本·加兰特

作家 博物馆之夜

3. 托马斯·列侬(1951)

作家 秋港勇士

4. 托马斯·列侬(1970)

作家 博物馆之夜

第二部电影

5. 肖恩·利维

经理 博物馆之夜

6. 杨红玉

经理 秋港勇士

编辑作为对您评论的回应:

这个逗号在组中的作用是什么

这是一个很好的后续问题!
|
操作符返回两组节点的并集,删除重复项并按文档顺序排列。它的操作数必须是节点集。但是,
groupby
值的第一部分不是一组节点,它只是一个字符串(函数返回一个字符串)。另一方面,逗号运算符
的操作数可以是任何类型的序列,也可以是
xs:string
类型的序列


简而言之,您必须使用
而不是
|
,因为这些运算符接受的操作数类型不同。这与分组没有任何关系。当构成分组键的所有序列都是节点集时,这两个运算符可以互换使用,保留订购中可能出现的更改。

hmm不确定这对我有用——我得到的值像是
788+Robert Ben Garant

,与任何电影编剧或导演都不匹配,因此没有标题谢谢!你的解释确实帮了一些忙,但有一个问题是,如果一个人是作家和导演,他们会在输出中出现两次,是不是因为你把我的小组中的|改成了?我可以编辑这个问题,以包括一个作家和导演在同一个人身上的例子,如果这有帮助的话。我将/concat(@differentior,'.'.',)添加到组中的导演,并修复了它。这个逗号在组中的作用是什么?谢谢你的帮助@用户3530461不客气。另外,这是一个有趣的问题,请看我的编辑。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="#all"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:functx="http://www.functx.com" version="2.0">
    <xsl:output method="html" indent="yes"/>

    <xsl:function name="functx:substring-after-last-match" as="xs:string"
        xmlns:functx="http://www.functx.com">
        <xsl:param name="arg" as="xs:string?"/>
        <xsl:param name="regex" as="xs:string"/>

        <xsl:sequence select="
            replace($arg,concat('^.*',$regex),'')
            "/>

    </xsl:function>

    <xsl:template match="mediaList">
        <html>
            <head>
                <link rel="stylesheet" type="text/css" href="CssJs/tableMedia.css"/>
                <title>Media Table</title>
            </head>
            <body>
                <table>
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>Person</th>
                            <th>Movies</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each-group select="movie" group-by="writer/concat(@differentiator, '_', .), director">
                            <xsl:sort
                                select="functx:substring-after-last-match(current-grouping-key(),'\s')"/>
                            <xsl:sort select="current-grouping-key()"/>

                           <xsl:variable name="person" select="if (contains(current-grouping-key(),'_')) then substring-after(current-grouping-key(),'_') else current-grouping-key()"/>
                            <xsl:variable name="year" select="if (contains(current-grouping-key(),'_')) then substring-before(current-grouping-key(),'_') else ''"/>

                            <tr>
                                <td>
                                    <xsl:value-of select="position()"/>
                                </td>
                                <td>
                                    <p>
                                        <a id="{concat(replace($person,' ',''),$year)}">
                                            <xsl:value-of select="if ($year) then concat($person,' (',$year,')') else $person"/>
                                        </a>
                                    </p>
                                </td>
                                <td>
                                    <xsl:if test="current-group()[writer = $person]">
                                        <h3>Writer</h3>
                                    </xsl:if>
                                    <xsl:apply-templates
                                        select="current-group()[writer = $person]/title[not(@type)]"/>
                                    <xsl:if test="current-group()[director = $person]">
                                        <h3>Director</h3>
                                    </xsl:if>
                                    <xsl:apply-templates
                                        select="current-group()[director = $person]/title[not(@type)]"
                                    />
                                </td>
                            </tr>
                        </xsl:for-each-group>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="title">
        <p>
            <xsl:value-of select="."/>
            <xsl:apply-templates select="../title[@type]"/>
        </p>
    </xsl:template>

    <xsl:template match="title[@type]">
        <span>
            <xsl:value-of select="concat(' (',.,')')"/>
        </span>
    </xsl:template>            
</xsl:stylesheet>
<mediaList>
        <movie id="1603934" dateCreated="2014-08-11">
          <title>Night at the Museum</title>
          <director>Shawn Levy</director>
          <LCSpecialTopics>Comedy</LCSpecialTopics>
          <writer>Robert Ben Garant</writer>
          <writer differentiator="1970">Thomas Lennon</writer>
          <language>English</language>
          <year>2006</year>
       </movie>
        <movie id="1603934" dateCreated="2014-08-11">
          <title>Second movie</title>
          <director>Frodo Baggins</director>
          <LCSpecialTopics>Comedy</LCSpecialTopics>
          <writer differentiator="1970">Thomas Lennon</writer>
          <language>English</language>
          <year>2006</year>
       </movie>

      <movie lastModified="2014-08-30" id="1123629" dateCreated="2014-08-04">
          <title type="foreign" xml:lang="cmn">Qiúgǎng Wèishì</title>
          <title>Warriors of Qiugang</title>
          <director>Ruby Yang</director>
          <LCSpecialTopics>Documentary films</LCSpecialTopics>
          <writer differentiator="1951">Thomas Lennon</writer>
          <language>Chinese</language>
          <year>2010</year>
       </movie>
</mediaList>
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <link rel="stylesheet" type="text/css" href="CssJs/tableMedia.css">
      <title>Media Table</title>
   </head>
   <body>
      <table>
         <thead>
            <tr>
               <th>#</th>
               <th>Person</th>
               <th>Movies</th>
            </tr>
         </thead>
         <tbody>
            <tr>
               <td>1</td>
               <td>
                  <p><a id="FrodoBaggins">Frodo Baggins</a></p>
               </td>
               <td>
                  <h3>Director</h3>
                  <p>Second movie</p>
               </td>
            </tr>
            <tr>
               <td>2</td>
               <td>
                  <p><a id="RobertBenGarant">Robert Ben Garant</a></p>
               </td>
               <td>
                  <h3>Writer</h3>
                  <p>Night at the Museum</p>
               </td>
            </tr>
            <tr>
               <td>3</td>
               <td>
                  <p><a id="ThomasLennon1951">Thomas Lennon (1951)</a></p>
               </td>
               <td>
                  <h3>Writer</h3>
                  <p>Warriors of Qiugang<span> (Qiúgǎng Wèishì)</span></p>
               </td>
            </tr>
            <tr>
               <td>4</td>
               <td>
                  <p><a id="ThomasLennon1970">Thomas Lennon (1970)</a></p>
               </td>
               <td>
                  <h3>Writer</h3>
                  <p>Night at the Museum</p>
                  <p>Second movie</p>
               </td>
            </tr>
            <tr>
               <td>5</td>
               <td>
                  <p><a id="ShawnLevy">Shawn Levy</a></p>
               </td>
               <td>
                  <h3>Director</h3>
                  <p>Night at the Museum</p>
               </td>
            </tr>
            <tr>
               <td>6</td>
               <td>
                  <p><a id="RubyYang">Ruby Yang</a></p>
               </td>
               <td>
                  <h3>Director</h3>
                  <p>Warriors of Qiugang<span> (Qiúgǎng Wèishì)</span></p>
               </td>
            </tr>
         </tbody>
      </table>
   </body>
</html>