如何将for-each元素用作模板的参数

时间:2019-03-03 13:18:16

标签: json xslt

我知道标题听起来不太能说明我的问题,请让我在下面进一步解释。

我有一个Java应用程序,它返回一个JSON数组,我的目标是将结果解析为String格式,以便在另一个“ C”应用程序中使用,这两个应用程序之间唯一可能的通信是String格式。

我已经使用XSLT通过对JSON响应内要查找的值进行硬编码来实现此目的,这是我的方法。

我的XML是:

<?xml version="1.0" encoding="UTF-8"?>
<input>[{"media_key":"1-1UL-12528","media_value":"10 RUE DES TRELISSAC","media_type":"Courrier"},{"media_key":"2-1UL-12528","media_value":"0614263770","media_type":"SMS"}]</input>

我的XSL是:

<?xml version="1.0" encoding="UTF-8" ?>

    

<xsl:template match="input">
    <output>
        <xsl:call-template name="print-object-values">
            <xsl:with-param name="string" select="."/>
        </xsl:call-template>
    </output>
</xsl:template>

<!-- Recupere la valeur d'une cle json String de type "key":"val" -->
<xsl:template name="get_string_json">
    <xsl:param name = "json" />
    <xsl:param name = "key" />

    <xsl:variable name="needle">
        <xsl:value-of select="concat('&quot;', $key, '&quot;:&quot;')" />
    </xsl:variable>

    <xsl:value-of select="substring-before(substring-after($json, $needle), '&quot;')" />
</xsl:template>


<xsl:template name="print-object-values">
    <xsl:param name="string"/>
    <xsl:param name="sep_values" select="';'" />

    <xsl:if test="contains($string,'media_key')">
        <xsl:text>|</xsl:text>

        <!-- Partie à modifier en récupérant les valeurs désiré par les fonctions déclarer prècedemment -->
        <xsl:call-template name="get_string_json">
            <xsl:with-param name="json" select="$string" />
            <xsl:with-param name="key" select="'media_key'" />
        </xsl:call-template>
        <xsl:value-of select="$sep_values" />
        <xsl:call-template name="get_string_json">
            <xsl:with-param name="json" select="$string" />
            <xsl:with-param name="key" select="'media_type'" />
        </xsl:call-template>
        <xsl:value-of select="$sep_values" />
        <xsl:call-template name="get_string_json">
            <xsl:with-param name="json" select="$string" />
            <xsl:with-param name="key" select="'media_value'" />
        </xsl:call-template>

        <xsl:call-template name="print-object-values">
            <xsl:with-param name="string" select="substring-after($string,'&quot;},{')"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

在我的打印对象值模板中,我使用打印对象值来获取JSON字符串中特定键的值。

我要执行的操作不是硬编码要搜索的字符串,有没有办法在变量中将其实现为映射,然后在for-each循环中使用它来执行get_string_json?

编辑:

这是我要实现的目标的一个示例

<xsl:template match="input">
    <output>
        <xsl:variable name="values">  <!-- declaration of the values to search for -->
            <value>
                <param>media_key</param>
                <param>media_type</param>
                <param>media_value</param>
            </value> 
        </xsl:variable>

        <xsl:call-template name="print-object-values">
            <xsl:with-param name="string" select="."/>
        </xsl:call-template>
    </output>
</xsl:template>

<xsl:template name="get_string_json">
    <xsl:param name = "json" />
    <xsl:param name = "key" />

    <xsl:variable name="needle">
        <xsl:value-of select="concat('&quot;', $key, '&quot;:&quot;')" />
    </xsl:variable>

    <xsl:value-of select="substring-before(substring-after($json, $needle), '&quot;')" />
</xsl:template>


<xsl:template name="print-object-values">
    <xsl:param name="string"/>
    <xsl:param name="sep_values" select="';'" />

    <xsl:if test="contains($string,'media_key')">
        <xsl:text>|</xsl:text>

        <xsl:for-each select= ><!-- select params in the variable values -->
            <xsl:call-template name="get_string_json">
                <xsl:with-param name="json" select="$string" />
                <xsl:with-param name="key" select="" /><!-- pass the value of the param -->
            </xsl:call-template>
        </xsl:for-each>
        <xsl:call-template name="print-object-values">
            <xsl:with-param name="string" select="substring-after($string,'&quot;},{')"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

1 个答案:

答案 0 :(得分:1)

重要提示:
该答案的目的是仅解决这部分问题:

  

而不是硬编码我要输入的字符串   搜索,有没有办法在变量中将其实现为地图   然后在for-each循环中使用它来执行get_string_json?

我发现有必要对XSLT的其他部分进行一些调整,但是我没有检查您的JSON解析方法。

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" encoding="UTF-8" indent="yes" />

<!-- declaration of the values to search for -->
<xsl:variable name="keys">  
    <key>media_key</key>
    <key>media_type</key>
    <key>media_value</key>
</xsl:variable>

<xsl:template match="input">
    <output>
        <xsl:call-template name="print-object-values">
            <xsl:with-param name="string" select="."/>
        </xsl:call-template>
    </output>
</xsl:template>

<xsl:template name="print-object-values">
    <xsl:param name="string"/>
    <xsl:param name="separator" select="'&quot;},{'" />

    <xsl:variable name="object" select="substring-before(concat($string, $separator), $separator)" />

    <xsl:text>|</xsl:text>

    <!-- HERE IS THE RELEVANT PART -->
    <xsl:for-each select="exsl:node-set($keys)/key">
        <xsl:call-template name="get_string_json">
            <xsl:with-param name="json" select="concat($object, '&quot;')" />
            <xsl:with-param name="key" select="." />
        </xsl:call-template>
        <xsl:if test="position()!=last()">
            <xsl:text>;</xsl:text>
        </xsl:if>
    </xsl:for-each>

    <xsl:if test="contains($string, $separator)">
        <xsl:call-template name="print-object-values">
            <xsl:with-param name="string" select="substring-after($string, $separator)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<!-- Recupere la valeur d'une cle json String de type "key":"val" -->
<xsl:template name="get_string_json">
    <xsl:param name = "json" />
    <xsl:param name = "key" />

    <xsl:variable name="needle">
        <xsl:value-of select="concat('&quot;', $key, '&quot;:&quot;')" />
    </xsl:variable>

    <xsl:value-of select="substring-before(substring-after($json, $needle), '&quot;')" />
</xsl:template>

</xsl:stylesheet>