Home > database >  Using Lookup tables in XSL to find corresponding values
Using Lookup tables in XSL to find corresponding values

Time:06-16

Need help with XSL lookup table. Ideally I want it to run on Saxon 9.5.1.6 but the example I found runs on Saxon 6.5.5.

I need to use a lookup table to find corresponding values. I have a lookup table in my XSL that contains the key that is in the XML and the corresponding value that I need add to the output XML.

My input XML looks like this:

<?xml version='1.0' encoding='UTF-8'?>
<doc>
    <obj>
        <BO>
            <OH>
                <Code>01</Code>
                <PC>C1</PC>
            </OH>
            <OH>
                <Code>02</Code>
                <PC>C2</PC>
            </OH>
            <OH>
                <Code>03</Code>
                <PC>C3</PC>
            </OH>
            <OH>
                <Code>04</Code>
                <PC>C4</PC>
            </OH>
        </BO>
    </obj>
</doc>

The desire output XML should look like this:

<doc>
   <obj>
      <OH>
         <Code>01</Code>
         <PC>C1</PC>
         <RT>10</RT>
      </OH>
      <OH>
         <Code>02</Code>
         <PC>C2</PC>
         <RT>5</RT>
      </OH>
      <OH>
         <Code>03</Code>
         <PC>C3</PC>
         <RT>20</RT>
      </OH>
      <OH>
         <Code>04</Code>
         <PC>C4</PC>
         <RT>40</RT>
      </OH>
   </obj>
</doc>

And this is my XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
        xmlns:lookup="lookup" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="lookup exsl">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8" media-type="xml/plain" />
    <xsl:strip-space elements="*" />
    
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" />
        </xsl:copy>
    </xsl:template>
    
    <xsl:param name="value_to_lookup" select="PC"/>
    
    <xsl:key name="lookup" match="row" use="@rt"/>
    
    <xsl:variable name="lookup" >
        <row PC="C1"   rt="10"/>
        <row PC="C2"   rt="5"/>
        <row PC="C3"   rt="20"/>
        <row PC="C3"   rt="40"/>
    </xsl:variable>
    
    <!--  drop elements  -->
    <xsl:template match="BO">
        <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="OH">
        <xsl:variable name="BPC" select="exsl:node-set($lookup)" />
        
        <OH>
            <Code>
                <xsl:value-of select="Code"/>
            </Code>
            <PC>
                <xsl:value-of select="PC"/>
            </PC>
            <RT>
                <xsl:for-each select="$BPC">
                    <xsl:value-of select="key('lookup', $value_to_lookup)/@rt"/>
                </xsl:for-each>
            </RT>
        </OH>
    </xsl:template>
</xsl:stylesheet>

CodePudding user response:

Try it this way?

XSLT 2.0

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

<xsl:key name="lookup" match="row" use="@PC"/>

<xsl:variable name="lookup" >
    <row PC="C1" rt="10"/>
    <row PC="C2" rt="5"/>
    <row PC="C3" rt="20"/>
    <row PC="C4" rt="40"/>
</xsl:variable>
    
<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!--  drop element  -->
<xsl:template match="BO">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="PC">
    <xsl:copy-of select="."/>
    <RT>
        <xsl:value-of select="key('lookup', ., $lookup)/@rt"/>
    </RT>
</xsl:template>

</xsl:stylesheet>
  • Related