【问题标题】:Parsing and storing values in array in XSLT 1.0在 XSLT 1.0 中解析和存储数组中的值
【发布时间】:2013-08-18 06:44:36
【问题描述】:

提前感谢您的支持。我只是遇到了一个问题,并尝试了很多方法。

我有一个 XSLT 1.0,需要通过逗号解析 xml 标记的值并将其存储在数组中。

val1,,val2,val3,,,val4

这里我需要通过逗号解析OPTIONS字段值,然后将其存储在数组中。在这里,我被困在将它存储在数组中以供进一步使用的方式。

请指教

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="text" omit-xml-declaration="yes"/>
    <xsl:variable name="inline-array">
        <!--<Item>A</Item>
        <Item>B</Item>
        <Item>C</Item>-->

        <xsl:call-template name="splitByComma">
            <xsl:with-param name="str" select="OPTIONS"/>
        </xsl:call-template>
    </xsl:variable>

    <xsl:template match="/">
        <xsl:param name="array" select="document('')/*/xsl:variable[@name='inline-array']/*"/>
        <xsl:value-of select="$array[1]"/>          
    </xsl:template>

    <xsl:template name="splitByComma">
        <xsl:param name="str"/>
        <xsl:choose>
            <xsl:when test="contains($str,',')">
                <item><xsl:value-of select="substring-before($str,',')"/></item>
                <xsl:call-template name="splitByComma">
                    <xsl:with-param name="str"
                        select="substring-after($str,',')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <item><xsl:value-of select="$str"/></item>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

【问题讨论】:

    标签: xslt xslt-1.0


    【解决方案1】:

    我认为这在 XSLT 1.0 中不起作用,因为当您尝试从样式表(即&lt;xsl:param name="array" select="document('')/*/xsl:variable[@name='inline-array']/*"/&gt;)加载变量内联数组的内容时,您实际上加载了它的定义。因此它包含元素 &lt;xsl:call-template... 和子 &lt;xsl:with-param... 不是评估它的结果。

    所以在这种情况下,您有两个选择:

    (1) 如果您的 xslt 处理器支持,请使用一些扩展函数,例如 xxx:node-set()

    例如,如果您使用 MS 处理器,您可以在样式表的文档元素中添加其命名空间:xmlns:msxsl="urn:schemas-microsoft-com:xslt"

    你可以从这个命名空间调用函数node-set()&lt;xsl:variable name="array" select="msxsl:node-set($inline-array)/item" /&gt;。这会将您的变量处理为节点集,您可以将其作为另一个 xml 访问:&lt;xsl:value-of select="$array[3]"/&gt;

    其他供应商也可能有这样的扩展 - 查看您的处理器的文档。或查看“exslt”。

    (2) 您还可以创建另一个递归命名模板,在您的 csv 字符串中占据所需值的位置。它只会在指定位置返回单个值。但对于更大的数据,它可能有点贵 - 这取决于您的预期输入。

    (3) 切换到 xslt 2.0 让这些事情变得更容易

    您可以在 xslt 2.0 中使用 tokenize() 函数

    <xsl:variable name="OPTIONS" select="'val1,,val2,val3,,,val4'" />
    <xsl:variable name="array" select="tokenize($OPTIONS, ',')" />
    <xsl:value-of select="$array[3]" />
    

    【讨论】:

    • @Jirka,该变量是全局变量,应在实际转换发生之前定义。我对吗 ?有一个我开始工作的例子。请点击此处的网址stackoverflow.com/questions/3299938/creating-arrays-in-xslt
    • 是的,我阅读了此链接,但有所不同。所描述的解决方案加载具有“静态”内容的变量。它只是读了它。你想阅读它(它确实)并解释它(它没有 - 如果它这样做,那么就没有任何理由调用 document() 函数)。因此,除了您的链接上的解决方案读取&lt;Item&gt; 序列并且什么都不做之外,它还从您的样式表中读取元素序列并且不再对它们做任何事情。变量是否是全局的并不重要。对于 document() 函数,您的 xslt 文件只是一个没有特殊含义的 xml 文件。
    • 是的,我现在明白了。我仍在为解决方案而苦苦挣扎。非常感谢。如果您提供一些代码示例来解决我的问题,请告诉我。
    • 我试图在我的回答中添加一些要点 - 看看它们。
    • Jirka,非常感谢您的 cmets。使用节点集,我得到了我需要的东西。您的支持让我对 xslt 有了更多的了解。
    猜你喜欢
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多