XSL - Embedded Lookup Table - Lookup Value of Variable

余生长醉 提交于 2019-12-23 20:37:01

问题


StackExchange, I'm hoping someone here can help me with this issue!

I'm working in XSLT 1.0, trying to embed a lookup table to convert some unformatted data to a standardized, formatted structure.

I have read and searched and tried various methods to accomplish this and none of them have been able to generate a result. (Though I'm not getting any errors, either.)

Below is a sample of the XSL I'm working with:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:lookup="lookup" exclude-result-prefixes="lookup">

<xsl:key name="lookup_table" match="lookup:table/row" use="@raw"/>

<lookup:table>
    <row raw="raw1" corrected="Raw One"/>
    <row raw="raw2" corrected="Raw Two"/>
    <row raw="raw3" corrected="Raw Three"/>
    <row raw="raw4" corrected="Raw Four"/>
    <row raw="raw5" corrected="Raw Five"/>
</lookup:table>

<xsl:template match="/">

<xsl:variable name="lookup_table" select='document("")//lookup:table/row'/>
<xsl:variable name="value_to_lookup" select="'raw1'"/>

        <!-- In the actual XSL document, this variable would use an XPath to point to another attribute. -->
        <!-- In this case, the value of this variable must be changed manually. -->

<xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/>

<xsl:value-of select='document("")//lookup:table[@raw = $value_to_lookup]/@corrected'/>

<xsl:value-of select='$lookup_table[@raw = $value_to_lookup]/@corrected'/>

<xsl:value-of select="key('lookup_table',$value_to_lookup)/@corrected"/>

    <!-- The above lines are the various methods I've seen documented on other websites that claim these methods should allow me to what I need to. -->
    <!-- There is no need to have multiple identical results, I only have multiple attempts here to document the steps I have tried. -->

</xsl:template>
</xsl:stylesheet>

The current output of this code is nothing (literally).

The desired output when the variable value_to_lookup is equal to "raw1" is:

Raw One

For further clarification, the desired output when the variable value_to_lookup is equal to "raw4" is:

Raw Four

The output of this bit of code will be stored in a variable and called later when needed.

Thanks again!


回答1:


-- edited in response to changes in the question --

Looking at the 4 options presented in your stylesheet:

  1. This works as expected:

    <xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/>
    
  2. This cannot work, because raw is an attribute of row, and row is absent from the path:

    <xsl:value-of select='document("")//lookup:table[@raw = $value_to_lookup]/@corrected'/>
    
  3. This works as expected:

    <xsl:value-of select='$lookup_table[@raw = $value_to_lookup]/@corrected'/>
    
  4. This doesn't work because in XSLT 1.0, keys only work in the context of current document:

    <xsl:value-of select="key('lookup_table',$value_to_lookup)/@corrected"/>
    

    To make it work, you would do:

    <xsl:for-each select="document('')">
        <xsl:value-of select="key('lookup_table',$value_to_lookup)/@corrected"/>
    </xsl:for-each>
    

-- added in response to the following clarifications in comments --

The XSL stylesheet is part of the application. When I want to generate a new resultant document or make changes to an existing one, I go through the menus of the Java-based application. I eventually arrive at a screen with a small menu on the side and large text-entry window in the middle. This text-entry window is where the XSL coding is typed.


what do you get as the result of <xsl:value-of select="count(document(''))"/>?


The result is "0".

Apparently, your processing environment does not support using the document() function to refer to the stylesheet itself. This means you will need to use another method to perform an internal lookup - namely, define a variable and convert it into a node-set - as was already suggested in the answer by MiMo.

Note that this has nothing to do with Java. Practically all XSLT 1.0 processors support the EXSLT node-set() extension function, but some Microsoft processors recognize it only in their own namespace.


For completion, here's how you would use a key to lookup a value from the variable:

XSLT 1.0

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

<xsl:param name="value_to_lookup" select="'raw1'"/>

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

<xsl:variable name="lookup">
    <row raw="raw1" corrected="Raw One"/>
    <row raw="raw2" corrected="Raw Two"/>
    <row raw="raw3" corrected="Raw Three"/>
    <row raw="raw4" corrected="Raw Four"/>
    <row raw="raw5" corrected="Raw Five"/>
</xsl:variable>
<xsl:variable name="lookup-set" select="exsl:node-set($lookup)" />

<xsl:template match="/">
    <!-- change context to the lookup "document" -->
    <xsl:for-each select="$lookup-set">
        <xsl:value-of select="key('lookup', $value_to_lookup)/@corrected"/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>



回答2:


The problem is that <xsl:variable name="value_to_lookup" select='raw1'/> sets value_to_lookup to the value of a (non existent) raw1 element - so it is empty.

What you want is <xsl:variable name="value_to_lookup" select="'raw1'"/> and then <xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/> works. Complete XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
            xmlns:lookup="lookup" exclude-result-prefixes="lookup">

<lookup:table>
    <row raw="raw1" corrected="Raw One"/>
    <row raw="raw2" corrected="Raw Two"/>
    <row raw="raw3" corrected="Raw Three"/>
    <row raw="raw4" corrected="Raw Four"/>
    <row raw="raw5" corrected="Raw Five"/>
</lookup:table>

<xsl:template match="/">
    <xsl:variable name="value_to_lookup" select="'raw1'"/>
    <xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/>
</xsl:template>

You can define the lookup table without using document() doing something like this:

<xsl:variable name="lookup_table_fragment">
    <row raw="raw1" corrected="Raw One"/>
    <row raw="raw2" corrected="Raw Two"/>
    <row raw="raw3" corrected="Raw Three"/>
    <row raw="raw4" corrected="Raw Four"/>
    <row raw="raw5" corrected="Raw Five"/>
</xsl:variable>
<xsl:variable name="lookup_table" select="msxsl:node-set($lookup_table_fragment)" />

and then:

<xsl:value-of select='$lookup_table/row[@raw = $value_to_lookup]/@corrected'/>

(msxsl:node-set is Microsoft-specific, but all processors have a function to convert a fragment to a node set)

This last version adapted for A Java XSLT processor reads:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
        xmlns:lookup="lookup" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="lookup exsl">

    <xsl:variable name="lookup_table_fragment">
        <row raw="raw1" corrected="Raw One"/>
        <row raw="raw2" corrected="Raw Two"/>
        <row raw="raw3" corrected="Raw Three"/>
        <row raw="raw4" corrected="Raw Four"/>
        <row raw="raw5" corrected="Raw Five"/>
    </xsl:variable>
    <xsl:variable name="lookup_table" select="exsl:node-set($lookup_table_fragment)" />

    <xsl:template match="/">
        <xsl:variable name="value_to_lookup" select="'raw1'"/>
        <xsl:value-of select='$lookup_table/row[@raw = $value_to_lookup]/@corrected'/>
   </xsl:template>

</xsl:stylesheet>

and can be tested at http://www.utilities-online.info/xsltransformation



来源:https://stackoverflow.com/questions/35327614/xsl-embedded-lookup-table-lookup-value-of-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!