问题
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:
This works as expected:
<xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/>
This cannot work, because
raw
is an attribute ofrow
, androw
is absent from the path:<xsl:value-of select='document("")//lookup:table[@raw = $value_to_lookup]/@corrected'/>
This works as expected:
<xsl:value-of select='$lookup_table[@raw = $value_to_lookup]/@corrected'/>
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