xml XSLT - 使用 XPath 计算子元素的数量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16021801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:58:57  来源:igfitidea点击:

XSLT - count the number of child elements by using XPath

xmlxsltxpathcount

提问by Alex

I have the following XML file that stores movies and actors details:

我有以下存储电影和演员详细信息的 XML 文件:

<database
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="movies.xsd">

<movies>
    <movie movieID="1">
        <title>Movie 1</title>
        <actors>
            <actor actorID="1">
                <name>Bob</name>
                <age>32</age>
                <height>182 cm</height>
            </actor>
            <actor actorID="2">
                <name>Mike</name>
            </actor>
        </actors>
    </movie>
</movies>

</database>

If the actorelement contains more than one child elements (in this case it's name, age and height) then I want to display its name as a hyperlink.

如果actor元素包含多个子元素(在本例中是名称、年龄和高度),那么我想将其名称显示为超链接。

If, however, the actorelement only contains one child element (name), then it should be displayed as plain text.

但是,如果该actor元素仅包含一个子元素(名称),则应将其显示为纯文本。

XSLT:

XSLT:

<xsl:template match="/">
    <div>
      <xsl:apply-templates select="database/movies/movie"/>
    </div>
  </xsl:template>

  <xsl:template match="movie">
    <xsl:value-of select="concat('Title: ', title)"/>
    <br />
    <xsl:text>Actors: </xsl:text>
    <xsl:apply-templates select="actors/actor" />
    <br />
  </xsl:template>    

<xsl:template match="actor">
    <xsl:choose>
        <xsl:when test="actor[count(*) &gt; 1]/name">
            <a href="actor_details.php?actorID={@actorID}">
                <xsl:value-of select="name"/>
            </a>
            <br/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="name"/>
            <br/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

So in this case Bob should be displayed as a hyperlink, and Mike should be displayed as plain text. However, my page displays both Bob and Mike as plain text.

所以在这种情况下,Bob 应该显示为超链接,而 Mike 应该显示为纯文本。但是,我的页面将 Bob 和 Mike 都显示为纯文本。

回答by Tim C

Your first xsl:whentest is incorrect here

你的第一个xsl:when测试在这里不正确

<xsl:when test="actor[count(*) &gt; 1]/name">

You are already positioned on an actorelement here, so this will be looking for an actorelement that is a child of the current actorelement, and finding nothing.

您已经定位在对演员的元素在这里,所以这将是寻找一个演员,它是当前的一个子元素演员元素,什么也没找到。

You probably just want to do this

你可能只想这样做

<xsl:when test="count(*) &gt; 1">

Alternatively, you could do this

或者,你可以这样做

<xsl:when test="*[2]">

i.e, is there an element in the second position (that saves counting all elements, when you only really want to check there is more than one),

即,第二个位置是否有一个元素(当您只想检查是否有多个元素时,可以节省对所有元素的计数),

Or perhaps you want to check the current actorelement has an element other than name?

或者您想检查当前actor元素是否有name以外的元素?

<xsl:when test="*[not(self::name)]">

As an aside, it might be better to put the test in a template match, rather than use an xsl:choose.

顺便说一句,最好将测试放在模板匹配中,而不是使用xsl:choose

Try this XSLT

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml-declaration="no"/>

   <xsl:template match="/">
      <div>
         <xsl:apply-templates select="database/movies/movie"/>
      </div>
   </xsl:template>

   <xsl:template match="movie">
      <xsl:value-of select="concat('Title: ', title)"/>
      <br/>
      <xsl:text>Actors: </xsl:text>
      <xsl:apply-templates select="actors/actor"/>
      <br/>
   </xsl:template>

   <xsl:template match="actor">
      <xsl:value-of select="name"/>
      <br/>
   </xsl:template>

   <xsl:template match="actor[*[2]]">
      <a href="actor_details.php?actorID={@actorID}">
         <xsl:value-of select="name"/>
      </a>
      <br/>
   </xsl:template>
</xsl:stylesheet>

Note that the XSLT processor should match the more specific template first in this instance.

请注意,在此实例中,XSLT 处理器应首先匹配更具体的模板。