Xml 从current-grouping-key()xslt中访问属性
我有一些包含数千个电影元素的xml,它们都可以有一个或多个导演和编剧元素,如果一个导演或编剧与另一个同名,如图所示,如果他们不是同一个人,我会添加一个@differentior of birthyearXml 从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> <
<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>