XSL - 嵌入式查找 Table - 变量的查找值

XSL - Embedded Lookup Table - Lookup Value of Variable

StackExchange,我希望这里有人可以帮助我解决这个问题!

我正在使用 XSLT 1.0,试图嵌入一个查找 table 以将一些未格式化的数据转换为标准化的格式化结构。

我已经阅读、搜索并尝试了各种方法来完成此操作,其中 none 已经能够生成结果。 (虽然我也没有收到任何错误。)

下面是我正在使用的 XSL 示例:

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

此代码的当前输出为空(字面意思)。

当变量value_to_lookup等于"raw1"时期望的输出是:

Raw One

为了进一步说明,当变量value_to_lookup等于"raw4"时所需的输出是:

Raw Four

这段代码的输出将存储在一个变量中,稍后需要时调用。

再次感谢!

问题是 <xsl:variable name="value_to_lookup" select='raw1'/>value_to_lookup 设置为(不存在的)raw1 元素的值 - 因此它是空的。

你想要的是 <xsl:variable name="value_to_lookup" select="'raw1'"/> 然后 <xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/> 就可以了。完整的 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>

您可以定义查找 table 而无需使用 document() 执行以下操作:

<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)" />

然后:

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

msxsl:node-set是微软特有的,但是所有的处理器都有将片段转换为节点集的函数)

最后一个适用于 A Java 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" 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>

并且可以在 http://www.utilities-online.info/xsltransformation

进行测试

--根据问题的变化进行编辑--

查看样式表中显示的 4 个选项:

  1. 这按预期工作:

    <xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/>
    
  2. 这行不通,因为rawrow的一个属性,而row 路径中不存在:

    <xsl:value-of select='document("")//lookup:table[@raw = $value_to_lookup]/@corrected'/>
    
  3. 这按预期工作:

    <xsl:value-of select='$lookup_table[@raw = $value_to_lookup]/@corrected'/>
    
  4. 这不起作用,因为在 XSLT 1.0 中,键只在上下文中起作用 当前文档的数量:

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

    要让它发挥作用,您可以这样做:

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

-- 添加以回应评论中的以下说明--

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

显然,您的处理环境不支持使用 document() 函数来引用样式表本身。这意味着您将需要使用另一种方法来执行内部查找——即定义一个变量并将其转换为节点集——正如 MiMo 在答案中已经建议的那样。

请注意,这与Java无关。实际上所有 XSLT 1.0 处理器都支持 EXSLT node-set() 扩展函数,但某些 Microsoft 处理器仅在其自己的命名空间中识别它。


为了完成,下面是使用键从变量中查找值的方法:

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>