XSLT: getting the maximum value from the obtained values ​​from the source XML nodes

I have an XML structure as shown below

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

There is a mapping available for these categories in an XML search form like this

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

Now I am looking for an XSLT solution that can return me the Max value as a result of the conversion without using the node-set extension function.

Here are my test cases

Test case 1:

Input:

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

Expected Result 3

Example 2:

Input:

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

Expected Result 3

Test case 3:

Input:

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

Expected Result 2

Test Case 4:

Input:

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

Expected Result 3

Test Example 5:

Input:

<Categories>
<cat>Video</cat>
</Categories>

Expected Result 1

Thanks in advance.

Update from comments :

[ document()]. for-each on , . .

, xsl , xslt, :

<xsl:value-of select='xx:lookupValue("MappingXML","Category",.,"COL1")'/>

. nodeet. , for-each, (RTF), XSLt 1.0, node -set().

+3
3

OP:

, xsl , xslt, : <xsl:value-of select='xx:lookupValue("MappingXML","Category",.,"COL1")'/>- satish

XSLT 2.0 XSLT 1.0 ( <xsl:function> ):

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

XML-:

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

, :

3

, XSLT 1.0:

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

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>

, ... , node node ( sibling), @Dimitre.

XPath/XSLT 2.0 :

max(Categories/cat/xx:lookupValue('MappingXML','Category',.,'COL1')
+1
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="/*">
        <xsl:variable name="docLookup" select="document('lookup_file.xml')/*/Lookup"/>
        <xsl:variable name="avElms" select="cat"/>
        <xsl:value-of select="$docLookup/mapping
                            [not(. &lt; ../../Lookup[cat = $avElms]/mapping)]/text()"/>
    </xsl:template>
</xsl:stylesheet>

Results:

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

Result 3

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

Result 3

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

Result 2

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

Result 3

<Categories>
    <cat>Video</cat>
</Categories>

Result 1

0
source

Source: https://habr.com/ru/post/1785279/


All Articles