使用 XPath 1.0 根据属性选择唯一元素值 [英] Select unique element values based on the attribute with XPath 1.0
问题描述
我有一个存储电影及其演员的 XML 文件.
<movie movieID="1"><演员><演员actorID="1"><name link="hello">Bob</name></演员><演员actorID="2"><name link="你好">迈克</name></演员></演员></电影><movie movieID="2"><演员><演员actorID="1"><name link="hello">Bob</name></演员><演员actorID="2"><姓名>丹尼尔</姓名></演员></演员></电影></电影>
从上面的代码可以看出,我有 2 个电影"元素,每个元素包含 2 个演员"子元素.4 个名称"子元素中有 3 个包含属性链接":Bob、Mike、Bob
我使用以下 XSLT 代码仅显示包含属性链接"的演员的姓名:
<xsl:text>演员:</xsl:text><xsl:apply-templates select="/movies/movie/actors/actor/name[@link]"/></xsl:模板><xsl:template match="name[@link]"><xsl:value-of select="."/><xsl:element name="br"/></xsl:模板>
我得到的输出:
鲍勃麦克风鲍勃
如您所见,Bob"这个名字重复了两次.我只想显示具有链接"属性的唯一演员姓名
我尝试了以下 XPath 1.0 查询:
<xsl:template match="[not(@name[@link] =前面::@name)]"><xsl:template match="not(@name[@link] =前面::@name)"><xsl:template match="not(@name[@link] =previous-sibling::@name)">
所有这些都使页面显示错误.
在 XSLT 1.0 中进行这种分组的有效方法是使用 Muenchian 分组(我添加了一个 div
和一个 br
为清楚起见;随意删除它们):
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/><xsl:key name="kName" match="actor/name[@link]" use="."/><xsl:template match="/"><div><xsl:text>演员:</xsl:text><br/><xsl:variable name="actorNames"select="/movies/movie/actors/actor/name[@link]"/><xsl:应用模板select="$actorNames[generate-id() =generate-id(key('kName', .)[1])]"/>
</xsl:模板><xsl:template match="name"><xsl:value-of select="."/><br/></xsl:模板></xsl:stylesheet>
在您的示例输入上运行时,会产生:
演员:<br/>鲍勃<br/>迈克<br/>
I have an XML file that stores movies and their actors.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="index.xsl"?>
<movies
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="movies.xsd">
<movie movieID="1">
<actors>
<actor actorID="1">
<name link="hello">Bob</name>
</actor>
<actor actorID="2">
<name link="hello">Mike</name>
</actor>
</actors>
</movie>
<movie movieID="2">
<actors>
<actor actorID="1">
<name link="hello">Bob</name>
</actor>
<actor actorID="2">
<name>Daniel</name>
</actor>
</actors>
</movie>
</movies>
As you can see from the code above, I have 2 "movie" elements that contain 2 "actor" child elements each. 3 out of 4 "name" child elements contain an attribute "link": Bob, Mike, Bob
I'm using the following XSLT code to display only the names of the actors that contain an attribute "link":
<xsl:template match="/">
<xsl:text>Actors: </xsl:text>
<xsl:apply-templates select="/movies/movie/actors/actor/name[@link]"/>
</xsl:template>
<xsl:template match="name[@link]">
<xsl:value-of select="." />
<xsl:element name="br" />
</xsl:template>
The output that I get:
Bob
Mike
Bob
As you can see the name "Bob" repeats twice. I want to display only unique actor names that have an attribute "link"
I have tried the following XPath 1.0 queries:
<xsl:template match="[not(@name[@link] = preceding::@name)]">
<xsl:template match="not(@name[@link] = preceding::@name)">
<xsl:template match="not(@name[@link] = preceding-sibling::@name)">
All of them made the page display an error.
The efficient way to do grouping like this in XSLT 1.0 is to use Muenchian grouping (I've added a div
and a br
for clarity; feel free to remove them):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kName" match="actor/name[@link]" use="." />
<xsl:template match="/">
<div>
<xsl:text>Actors: </xsl:text>
<br />
<xsl:variable name="actorNames"
select="/movies/movie/actors/actor/name[@link]"/>
<xsl:apply-templates
select="$actorNames[generate-id() =
generate-id(key('kName', .)[1])]" />
</div>
</xsl:template>
<xsl:template match="name">
<xsl:value-of select="." />
<br />
</xsl:template>
</xsl:stylesheet>
When run on your sample input, this produces:
<div>
Actors: <br />Bob<br />Mike<br />
</div>
这篇关于使用 XPath 1.0 根据属性选择唯一元素值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!