【问题标题】:XSLT iterate array and apply generic template to sub elements(Xml to Json)XSLT 迭代数组并将通用模板应用于子元素(Xml 到 Json)
【发布时间】:2017-11-12 14:14:06
【问题描述】:

我不会得到。 xml,我必须使用 XSLT 将它们转换为适当的 json 格式。我能够转换除数组之外的所有内容。我需要保持模板通用。

Here 是要点 示例 示例(XML、XSL 和结果),其场景为 - 帐户有 m 部门有 n 员工。

XSL 适用于所有场景,包括复杂对象。但它不会将理想的 JSON 格式应用于数组。它还将对象名称附加到数组的每个单独元素。实际上我有非常复杂/嵌套的 xml,所以我必须让 xslt 尽可能通用。

如果我添加以下两个模板,它不会在叶节点后添加逗号。

<xsl:template match="departments">
    <xsl:text>"departments": [{</xsl:text>
    <xsl:for-each select=".//department">
        <xsl:if test="position() > 1">
            <xsl:text>},{</xsl:text>
        </xsl:if>
        <xsl:apply-templates />
    </xsl:for-each>
    <xsl:text>}]</xsl:text>
</xsl:template>

<xsl:template match="employees">
    <xsl:text>"employees": [{</xsl:text>
    <xsl:for-each select=".//employee">
        <xsl:if test="position() > 1">
            <xsl:text>},{</xsl:text>
        </xsl:if>
        <xsl:apply-templates />
    </xsl:for-each>
    <xsl:text>}]</xsl:text>
</xsl:template>

我也在 gist 中复制了 expected-result.json。有没有办法迭代数组的子元素并将模板应用于嵌套对象或任何其他逻辑?

【问题讨论】:

  • 我一般用w3schools来测试快速转换。
  • 至少,您必须指出(可能在 XSLT 中的变量中)哪些元素需要被视为数组。否则,您的 XSLT 不可能知道输出 JSON 数组而不是对象。 TBH,我认为 XSLT 不是将 XML 转换为 JSON 的一个很好的选择。您打算如何处理生成有效 JSON 所需的所有复杂转义规则?
  • @JLRishe 是的,我们需要指定需要被视为数组的元素。我起草了有问题的实施。但需要改进。它更多地是关于生成定制的 JSON。我只需要告知需要被视为数组的元素。其他一切都由我共享的模板处理。
  • 我不明白为什么gist.github.com/anonymous/… 是JSON,是不是整个内容都缺少一对花括号以使其成为对象?
  • @MartinHonnenI 我已更新 XSL 及其结果为新的 gist url(更新问题)。 result.json 仍然不是有效的 json,我想作为这个问题的一个范围来解决。

标签: arrays json xml xslt type-conversion


【解决方案1】:

添加新模板array-obj 并从匹配字段employeesdepartments 的模板调用它。

<xsl:template name="array-obj">
    <xsl:text>{
</xsl:text>
    <xsl:for-each select="*">
        <xsl:if test="position() > 1">
            <xsl:text>,
</xsl:text>
        </xsl:if>
        <xsl:apply-templates select="."/>
    </xsl:for-each>
        <xsl:text>
</xsl:text>
    <xsl:text>}</xsl:text>
</xsl:template>

employeesdepartments 模板需要修改如下。从模板中删除大括号。

<xsl:template match="employees">
    <xsl:text>"employees": [</xsl:text>
    <xsl:for-each select=".//employee">
        <xsl:if test="position() > 1">
            <xsl:text>,</xsl:text>
        </xsl:if>
        <xsl:call-template name="array-obj"/>
    </xsl:for-each>
    <xsl:text>]</xsl:text>
</xsl:template>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    相关资源
    最近更新 更多