XSLT:从源XML节点的派生值中获取最大值

XSLT:从源XML节点的派生值中获取最大值,xml,xslt,Xml,Xslt,我有一个如下所示的XML结构 <Categories> <cat>Video</cat> <cat>Audio</cat> <cat>Hybrid</cat> </Categories> 此函数返回字符串。这 函数不返回节点集。我 通过捕获所有 执行后的派生值 ,但需进一步处理 此变量输出(RTF),用XSLt表示 1.0中,我没有任何node-set()函数的句柄 结果是3 <Categor

我有一个如下所示的XML结构

<Categories>
<cat>Video</cat>
<cat>Audio</cat>
<cat>Hybrid</cat>
</Categories>
此函数返回字符串。这 函数不返回节点集。我 通过捕获所有 执行后的派生值
,但需进一步处理
此变量输出(RTF),用XSLt表示
1.0中,我没有任何node-set()函数的句柄

结果是
3

<Categories>
    <cat>Video</cat>
    <cat>Hybrid</cat>
</Categories>
<Categories>
    <cat>Video</cat>
    <cat>Audio</cat>
</Categories>
<Categories>
    <cat>Video</cat>
</Categories>
结果是
3

<Categories>
    <cat>Video</cat>
    <cat>Hybrid</cat>
</Categories>
<Categories>
    <cat>Video</cat>
    <cat>Audio</cat>
</Categories>
<Categories>
    <cat>Video</cat>
</Categories>

视频

根据OP的评论,结果是
1

<Categories>
    <cat>Video</cat>
    <cat>Audio</cat>
    <cat>Hybrid</cat>
</Categories>
3
<xsl:stylesheet version="12.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xx="Your Namespace Here"
 >
 <xsl:output omit-xml-declaration="yes"/>

 <xx:lookup>
    <ValueSet>
        <Lookup>
            <cat>Video</cat>
            <mapping>1</mapping>
        </Lookup>
        <Lookup>
            <cat>Audio</cat>
            <mapping>2</mapping>
        </Lookup>
        <Lookup>
            <cat>Hybrid</cat>
            <mapping>3</mapping>
        </Lookup>
    </ValueSet>
 </xx:lookup>

 <!-- You probably don't need this and the above embedded XML -->
 <xsl:variable name="vlookupDoc" select="document('')/*/xx:lookup"/>

    <xsl:template match="/*">
      <xsl:call-template name="getMax">
        <xsl:with-param name="pNodes" select="cat"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="getMax">
      <xsl:param name="pcurrMax" select="-9999999999"/>
      <xsl:param name="pNodes"/>

      <xsl:choose>
       <xsl:when test="not($pNodes)">
         <xsl:value-of select="$pcurrMax"/>
       </xsl:when>
       <xsl:otherwise>
       <!-- Change the call of the ext. function as appr. -->
         <xsl:variable name="vNewVal" select=
         "number(xx:lookupValue($vlookupDoc,$pNodes[1]))"/>
         <xsl:call-template name="getMax">
          <xsl:with-param name="pNodes" select="$pNodes[position() >1]"/>
          <xsl:with-param name="pcurrMax" select=
           "($pcurrMax >= $vNewVal)*$pcurrMax
           +
            ($vNewVal > $pcurrMax)*$vNewVal"/>
         </xsl:call-template>
       </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

我有一个xsl提供的扩展 引擎处理器,以获取此信息 xslt如下所示:
–萨蒂什

这适用于XSLT 2.0,必须适用于XSLT 1.0(只需删除
并使用扩展函数):

转换为XSLT 1.0的代码

<Categories>
    <cat>Video</cat>
    <cat>Audio</cat>
    <cat>Hybrid</cat>
</Categories>
3
<xsl:stylesheet version="12.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xx="Your Namespace Here"
 >
 <xsl:output omit-xml-declaration="yes"/>

 <xx:lookup>
    <ValueSet>
        <Lookup>
            <cat>Video</cat>
            <mapping>1</mapping>
        </Lookup>
        <Lookup>
            <cat>Audio</cat>
            <mapping>2</mapping>
        </Lookup>
        <Lookup>
            <cat>Hybrid</cat>
            <mapping>3</mapping>
        </Lookup>
    </ValueSet>
 </xx:lookup>

 <!-- You probably don't need this and the above embedded XML -->
 <xsl:variable name="vlookupDoc" select="document('')/*/xx:lookup"/>

    <xsl:template match="/*">
      <xsl:call-template name="getMax">
        <xsl:with-param name="pNodes" select="cat"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="getMax">
      <xsl:param name="pcurrMax" select="-9999999999"/>
      <xsl:param name="pNodes"/>

      <xsl:choose>
       <xsl:when test="not($pNodes)">
         <xsl:value-of select="$pcurrMax"/>
       </xsl:when>
       <xsl:otherwise>
       <!-- Change the call of the ext. function as appr. -->
         <xsl:variable name="vNewVal" select=
         "number(xx:lookupValue($vlookupDoc,$pNodes[1]))"/>
         <xsl:call-template name="getMax">
          <xsl:with-param name="pNodes" select="$pNodes[position() >1]"/>
          <xsl:with-param name="pcurrMax" select=
           "($pcurrMax >= $vNewVal)*$pcurrMax
           +
            ($vNewVal > $pcurrMax)*$vNewVal"/>
         </xsl:call-template>
       </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

视频
1.
音频
2.
混合的
3.

这是XSLT的经典最大算法:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xx="extension-URI">
    <xsl:template match="/">
        <xsl:for-each select="Categories/cat">
            <xsl:sort select="xx:lookupValue('MappingXML',
                                             'Category',
                                             .,
                                             'COL1')"
                      data-type="number"
                      order="descending"/>
            <xsl:if test="position()=1">
                <xsl:value-of select="xx:lookupValue('MappingXML',
                                                     'Category',
                                                     .,
                                                     'COL1')"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

谢谢你的快速解决方案。尽管如此,我的查找信息无法像您在这里那样加载。我需要对每个类别进行输入,然后导出查找值。在那之后,我需要得到最大值。请修改您的解决方案以支持此操作,好吗?如果您无法通过document()获取,除了从外部文件读取任何信息外,您如何执行其他操作?或者查找信息在同一个文件中?我有一个xsl引擎处理器的扩展名,可以在xslt中使用,如下所示:您应该在问题中指出这一点。这个函数返回什么数据类型?很抱歉在原始问题中没有提到。这个函数返回字符串。好问题,+1。有关完整的解决方案,请参见我的答案。:)这很有效。谢谢你的解决方案。顺便说一句,你能解释一下thuis line的功能吗?您好,我正在尝试筛选传递给模板的节点,但失败了。这里的错误是什么?类别/cat[text()=“音频”或“视频”]。如果我只有Categories/cat[text()='Audio'],它就可以正常工作。请帮忙。我还尝试了Categories/cat[text()=“Audio”或text()=“Video”],但没有成功。@satish:这个XPath表达式返回两个值中的较大值。它使用了这样一个事实,即在XPath 1.0中将
true()
自动转换为
1
并将
false()
转换为
0
@satish:Use:
谢谢,这个表达式可以很好地过滤。很抱歉再次询问您,请您详细说明($pcurrMax>=$vNewVal)*$pcurrMax+($vNewVal>$pcurrMax)*$vNewVal。*是乘数吗?那么为什么会有一个+感谢这个解决方案。它很有魅力。如果我有更多,这种方法是否会影响性能?有没有办法从性能的角度进一步优化它?@satish:这只是一个额外的调用。因此,
cat
元素越多,对性能的影响就越小。
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xx="my:xx"
 >
 <xsl:output omit-xml-declaration="yes"/>

 <xx:lookup>
    <ValueSet>
        <Lookup>
            <cat>Video</cat>
            <mapping>1</mapping>
        </Lookup>
        <Lookup>
            <cat>Audio</cat>
            <mapping>2</mapping>
        </Lookup>
        <Lookup>
            <cat>Hybrid</cat>
            <mapping>3</mapping>
        </Lookup>
    </ValueSet>
 </xx:lookup>

 <xsl:variable name="vlookupDoc" select="document('')/*/xx:lookup"/>

    <xsl:template match="/*">
      <xsl:call-template name="getMax">
        <xsl:with-param name="pNodes" select="cat"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="getMax">
      <xsl:param name="pcurrMax" select="-9999999999"/>
      <xsl:param name="pNodes"/>

      <xsl:choose>
       <xsl:when test="not($pNodes)">
         <xsl:value-of select="$pcurrMax"/>
       </xsl:when>
       <xsl:otherwise>
         <xsl:variable name="vNewVal" select=
         "number(xx:lookupValue($vlookupDoc,$pNodes[1]))"/>
         <xsl:call-template name="getMax">
          <xsl:with-param name="pNodes" select="$pNodes[position() >1]"/>
          <xsl:with-param name="pcurrMax" select=
           "number(($pcurrMax >= $vNewVal))*$pcurrMax
           +
            number(($vNewVal > $pcurrMax))*$vNewVal"/>
         </xsl:call-template>
       </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

    <xsl:function name="xx:lookupValue">
      <xsl:param name="pLookupDoc"/>
      <xsl:param name="pCat"/>

      <xsl:value-of select=
        "$pLookupDoc/*/*[cat=$pCat]/mapping"/>
    </xsl:function>
</xsl:stylesheet>
<Categories>
    <cat>Video</cat>
    <cat>Audio</cat>
    <cat>Hybrid</cat>
</Categories>
3
<xsl:stylesheet version="12.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xx="Your Namespace Here"
 >
 <xsl:output omit-xml-declaration="yes"/>

 <xx:lookup>
    <ValueSet>
        <Lookup>
            <cat>Video</cat>
            <mapping>1</mapping>
        </Lookup>
        <Lookup>
            <cat>Audio</cat>
            <mapping>2</mapping>
        </Lookup>
        <Lookup>
            <cat>Hybrid</cat>
            <mapping>3</mapping>
        </Lookup>
    </ValueSet>
 </xx:lookup>

 <!-- You probably don't need this and the above embedded XML -->
 <xsl:variable name="vlookupDoc" select="document('')/*/xx:lookup"/>

    <xsl:template match="/*">
      <xsl:call-template name="getMax">
        <xsl:with-param name="pNodes" select="cat"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="getMax">
      <xsl:param name="pcurrMax" select="-9999999999"/>
      <xsl:param name="pNodes"/>

      <xsl:choose>
       <xsl:when test="not($pNodes)">
         <xsl:value-of select="$pcurrMax"/>
       </xsl:when>
       <xsl:otherwise>
       <!-- Change the call of the ext. function as appr. -->
         <xsl:variable name="vNewVal" select=
         "number(xx:lookupValue($vlookupDoc,$pNodes[1]))"/>
         <xsl:call-template name="getMax">
          <xsl:with-param name="pNodes" select="$pNodes[position() >1]"/>
          <xsl:with-param name="pcurrMax" select=
           "($pcurrMax >= $vNewVal)*$pcurrMax
           +
            ($vNewVal > $pcurrMax)*$vNewVal"/>
         </xsl:call-template>
       </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xx="extension-URI">
    <xsl:template match="/">
        <xsl:for-each select="Categories/cat">
            <xsl:sort select="xx:lookupValue('MappingXML',
                                             'Category',
                                             .,
                                             'COL1')"
                      data-type="number"
                      order="descending"/>
            <xsl:if test="position()=1">
                <xsl:value-of select="xx:lookupValue('MappingXML',
                                                     'Category',
                                                     .,
                                                     'COL1')"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
max(Categories/cat/xx:lookupValue('MappingXML','Category',.,'COL1')