1

所以我以前从未使用过 XSLT,而且我只以最简单的形式使用过 XPath。我有一个 Xml 元素“地球”,它有两个属性 Stamina 和 willpower。两者都包含数字。我要做的是在“地球”一词旁边显示这些属性中最小的值。我似乎无法锻炼如何在 XPath 中调用函数。

这是我的 XSLT

    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  version="2.0">
  <!--<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    -->

  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates select="//Rings"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="//Rings">
    <h2>Rings</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Earth</th>
        <th>
          <xsl:value-of select="fn:min(fn:number(Earth/@*))"/>
        </th>
      </tr>
      </tr>
    </table>
  </xsl:template>
</xsl:stylesheet>
4

3 回答 3

2

MS Visual Studio 预装了 .NET XSLT 处理器 XslCompiledTransform,这是一个 XSLT 1.0 处理器。

另一方面,min()是 XPath 2.0 中的标准函数,而不是 XPath 1.0 中的标准函数。XSLT 1.0 仅使用 XPath 1.0。

该问题的 XSLT 1.0 解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="Earth">
     <xsl:value-of select=
      "@*[not(. > ../@*)][1]"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时(因为您还没有提供一个!):

<Rings>
 <Earth stamina="3" willpower="6"/>
</Rings>

产生了想要的正确结果

3

在 .NET 中,可以使用第三方 XSLT 2.0 处理器,例如 Saxon.NET 或 XQSharp。下面是一个 XSLT 2.0 解决方案:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="Earth">
     <xsl:sequence select="min(@*)[1]"/>
 </xsl:template>
</xsl:stylesheet>
于 2011-10-22T14:32:04.657 回答
2

另请注意,这min(number(@*))在 XPath 2.0 中是不正确的——您不能将 number() 函数应用于节点序列以获取数字序列。应该是min(@*/number())。但是,如果输入未经验证,所有属性都将是 untypedAtomic,并且 min() 函数将自动将 untypedAtomic 值转换为数字。但是,如果有属性不是数值型的,那么自动转换就会出错,而使用number()会产生一个NaN值,这会导致min()的结果也是NaN。如果您想要所有这些数字属性的最小值,请尝试min(@*[. castable as xs:double]).

于 2011-10-22T18:01:14.227 回答
0

min()功能仅在 XSLT 2.0 中可用。您应该尝试使用 2.0 处理器 ( Saxon )。

于 2011-10-22T05:04:12.613 回答