XSL检查是否已生成某些特定的outpur

时间:2015-06-03 18:11:21

标签: json xml xslt

我正在尝试使用XSL将一些现有的XML文件转换为JSON结构。根据它们的值,我需要将一些元素放入JSON数组中。要使用正确的语法生成JSON字符串,我需要动态决定是否在对象后面(或在前面)放置逗号,因为JSON不允许在数组中使用尾随逗号。

XML文件看起来有点像:

<list>
    <type_a>
        <active>0</active>
        <data_a>don't put me to JSON...</data_a>
    </type_a>
    <type_b>
        <active>1</active>
        <data_b>put me to JSON</data_b>
    </type_b>
    <type_c>
        <active>1</active>
        <data_c>me too...</data_c>
    </type_c>
</list>

要转换的XSL如下所示:

<xsl:template match="/list">
[
    <xsl:if test="type_a/active != 0">
      { "type": "type_a",
        "data": <xsl:value-of select="type_a/data_a" /> }
    </xsl:if>
    <xsl:if test="type_b/active != 0">
      { "type": "type_b",
        "data": <xsl:value-of select="type_b/data_b" /> }
    </xsl:if>
    <xsl:if test="type_c/active != 0">
      { "type": "type_c",
        "data": <xsl:value-of select="type_c/data_c" /> }
    </xsl:if>
]
</xsl:template>

问题是,我需要在不同的{ }对象之间放置逗号,但不能在最后一个对象之后放置逗号。我看到的唯一两个解决方案是,在将对象(<xsl-if test="type_a/active != 0 or type_b/active != 0">, </xsl-if>;放在第三个对象之前)之前检查前面的任何对象是否处于活动状态,或者将XML转换为一些不太奇怪的中间对象XML首先。特别是第一个选项会非常难看,因为实际上我必须检查超过3种对象类型。 XML格式由一些遗留应用程序生成,无法更改。

由于使用XSL将XML结构传输到某些无XML输出,我是否还有进一步的麻烦?

1 个答案:

答案 0 :(得分:0)

一种方法是检查前面的兄弟是否存在并且是否处于活动状态,如果是,则插入,。我已经编辑了你的模板以反映这一点,但我会写一个函数来传递节点,让你的生活更轻松,而不是为每个兄弟重复模板。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:func="http://example.com/function"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output encoding="UTF-8" indent="yes" method="xml"/>

<xsl:template match="/list">
    [
    <xsl:sequence select="func:processing(type_a)"/>
    <xsl:sequence select="func:processing(type_b)"/>
    <xsl:sequence select="func:processing(type_c)"/>
    ]
</xsl:template>

<xsl:function name="func:processing">
    <xsl:param name="type"/>
    <xsl:for-each select="$type">
        <xsl:if test="active != 0">
            { "type": <xsl:value-of select="local-name()" />,
            "data": <xsl:value-of select="data_a" /> }
            <xsl:if test="following-sibling::*[1] and following-sibling::*[1]/active!=0">
                ,  
            </xsl:if>
        </xsl:if>
    </xsl:for-each>
</xsl:function>

</xsl:stylesheet>