2013-03-16 135 views
1

我有一个存储电影及其演员的XML文件。根据属性使用XPath 1.0选择唯一的元素值

<?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> 

从上面的代码可以看出,我有2个“电影”元素,每个元素包含2个“actor”子元素。 3/4“name”子元素包含属性“link”:Bob,Mike,Bob

我使用以下XSLT代码来仅显示包含属性“链接”的actor的名称:

<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> 

,我得到的输出:

Bob 
Mike 
Bob 

正如你可以看到名为 “鲍勃” 重复两次。我希望显示有一个属性“链接”

我曾尝试下面的XPath 1.0仅查询唯一的演员的名字:

<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)"> 

他们都取得了页面显示错误。

回答

2

的有效的方式做到这样的分组在XSLT 1.0是使用Muenchian分组的(我已经添加了div和清晰度br;随意删除):

<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> 

当上运行你的样品输入,这产生:

<div> 
    Actors: <br />Bob<br />Mike<br /> 
</div> 
+0

这很完美。了解更有效的定义独特元素的方法是很好的。谢谢! – Alex 2013-03-16 23:15:55