【问题标题】:XSL - Embedded Lookup Table - Lookup Value of VariableXSL - 嵌入式查找表 - 变量的查找值
【发布时间】:2016-02-10 22:55:09
【问题描述】:

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

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

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

以下是我正在使用的 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

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

再次感谢!

【问题讨论】:

    标签: xml xslt lookup lookup-tables


    【解决方案1】:

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

    查看样式表中显示的 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>
      

    --为响应 cmets 中的以下说明而添加--

    XSL 样式表是应用程序的一部分。当我想生成 一个新的结果文件或对现有文件进行更改,我去 通过基于 Java 的应用程序的菜单。我终于到了 在侧面有一个小菜单和大文本输入窗口的屏幕上 在中间。此文本输入窗口是 XSL 编码所在的位置 打字。


    &lt;xsl:value-of select="count(document(''))"/&gt; 的结果是什么?


    结果为“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>
    

    【讨论】:

    • 是的,你说得对。细微的变化。我已经实现了它们,并完全按照上面的方式复制了您的代码,但是您的代码仍然没有产生任何输出。该问题似乎与document('') 有关。作为测试,如果我在document('') 标签内输入&lt;xsl:value-of select="$value_to_lookup"/&gt;,我根本没有得到任何输出。但是,当在标签之外输入时,我至少可以看到$value_to_lookup 确实设置为“raw1”。有什么建议吗?
    • Michael,我在实际生产的XSL文档中试过了。任何放在&lt;xsl:for-each select="document('')"&gt; 标签内的东西都不会产生结果。我使用xsl:value-of 语句在标签内调用了一些已知良好的变量进行测试,但它们也没有显示任何内容。此外,当在这些标签之外调用时,您提出的变量显示了正确的存储值。这就是让我相信&lt;xsl:for-each select="document('')"&gt; 代码是问题所在。
    • 对,我相信这是通过基于 Java 的应用程序完成的。 XSL 样式表是应用程序的一部分。当我想生成一个新的结果文档或对现有文档进行更改时,我会浏览基于 Java 的应用程序的菜单。我最终到达了一个屏幕,侧面有一个小菜单,中间有一个大的文本输入窗口。这个文本输入窗口是输入 XSL 编码的地方。生成的文档将选定的 XSL 应用于当时正在处理的特定 XML,然后生成基于 HTML 的输出文档。这有助于回答问题吗?
    • Michael,使用&lt;xsl:value-of select="system-property('xsl:vendor')" /&gt;,我检索到了“Apache Software Foundation”。这有帮助吗?
    • 迈克尔,您更新的解决方案正在运行!感谢您的帮助和耐心,以及您的详尽回答。他们非常感激。就速度/性能和可靠性而言,答案是更好的选择,还是只是对使用哪个的偏好?
    【解决方案2】:

    问题在于&lt;xsl:variable name="value_to_lookup" select='raw1'/&gt;value_to_lookup 设置为(不存在的)raw1 元素的值 - 所以它是空的。

    你想要的是&lt;xsl:variable name="value_to_lookup" select="'raw1'"/&gt; 然后&lt;xsl:value-of select='document("")//lookup:table/row[@raw = $value_to_lookup]/@corrected'/&gt; 工作。完成 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>
    

    您可以在不使用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 是 Microsoft 特有的,但所有处理器都具有将片段转换为节点集的功能)

    最后一个适用于 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进行测试

    【讨论】:

    • 好的,这已经解决了部分问题。该变量现在被正确定义为“raw1”,但是“Raw One”的最终输出不显示。
    • 我在答案中添加了我用来测试的完整 XSLT - 它对我有用 - 输出只是字符串 Raw One
    • 您的两种方法似乎都不起作用。实际上,仅使用变量的替代方法会使输出表崩溃。 (它只显示空白,没有其他内容 - 甚至是以前存在/工作的内容。)建议?
    • ...也许document() 在您的 XSLT 处理器中不起作用?第二个版本使用 Microsoft 特定功能,因此如果您没有该功能(并且不定义其命名空间),它将无法工作。我使用 Java 扩展添加了第二个示例的一个版本和一个可以对其进行测试的 URL。
    • 命名空间“msxsl”在实际的 XML 文档中被声明为 xmlns:msxsl="urn:schemas-microsoft-com:xslt",因此您可能正在了解处理器是否存在限制。我将尝试基于 Java 的版本。
    猜你喜欢
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2023-01-10
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多