使用 XPath 1.0 根据属性选择唯一元素值 [英] Select unique element values based on the attribute with XPath 1.0

查看:23
本文介绍了使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆