【问题标题】:XSLT 3.0 iterate over JSON array wrapped in XMLXSLT 3.0 迭代用 XML 包装的 JSON 数组
【发布时间】:2017-10-27 09:23:02
【问题描述】:

我正在使用 XSLT 处理各种 XML 文件。在一个 XML 中,我发现了一个包装好的 JSON 列表:

<list><![CDATA[[
    {
    "title": "Title 1",
    "value": "Value 1",
    "order": 1
    },
    {
    "title": "Title 2",
    "value": "Value 2",
    "order": 2
    }
]]]>
</list>

我的问题是我需要遍历列表。例如:

<xsl:variable name="listVar">
    <!-- do something with list -->
</xsl:variable>
<xsl:for-each select="$listVar">
    <!-- do something with objects in list e.g. -->
    <xsl:value-of select="title"/>
    <xsl:value-of select="value"/>
</xsl:for-each>

如何用 XSLT 做到这一点?我使用 XSLT 3.0 和 Saxon 引擎,版本 9.8 HE。

考虑的解决方案:

1。 使用parse-json函数:

但是由于 XPathException,我无法迭代结果:“子轴的上下文项的必需项类型是 node();提供的值 (.) 具有项类型 array(function(*))”或“地图不能被原子化”。我发现有 可能我应该考虑的函数,如 map:get、map:entry,但到目前为止我还没有在我的案例中使用它们。

2。 上述变换前的附加变换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="3.0">
    <xsl:output method="xml" encoding="UTF-8" indent="no"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="list">
        <list>
            <xsl:copy-of select="json-to-xml(.)"/>
        </list>
    </xsl:template>
</xsl:stylesheet>

然后:

<xsl:variable name="listVar" select="list/array/map"/>

但它不起作用 - 可能是由于添加了命名空间

<list>
    <array xmlns="http://www.w3.org/2005/xpath-functions">
        <map>
...

【问题讨论】:

  • 你必须同时使用 XML 解析器和 JSON 解析器。
  • 另外请注意,如果您正在迁移到 XSLT 3.0,您可以通过声明 &lt;xsl:mode on-no-match="shallow-copy"/&gt; 来更紧凑地表达您似乎想要与您的第一个模板一起使用的身份转换。

标签: json xslt xslt-3.0


【解决方案1】:

当使用parse-json 解析时,您的 JSON 结构会在 XSLT/XPath 端为您提供 arraymaps,处理单个数组项的最直接方法是使用 ?* lookup operator,然后你可以使用for-each 甚至apply-templates:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:template match="list">
        <xsl:apply-templates select="parse-json(.)?*"/>
    </xsl:template>

    <xsl:template match=".[. instance of map(xs:string, item())]">
        <xsl:value-of select="?title, ?value"/>
    </xsl:template>
</xsl:stylesheet>

在哪里访问地图值,您可以再次使用?foo,如上所示。

至于使用json-to-xml 返回的 XML,它返回 XPath 函数命名空间中的元素,以便选择它们,就像命名空间中的任何其他元素一样,您需要确保使用例如设置命名空间。 xpath-default-namespace 用于您要处理来自该命名空间的元素的部分,或者您可以使用命名空间通配符,例如*:array/*:map.

【讨论】:

    猜你喜欢
    • 2021-11-08
    • 2018-08-03
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 2021-10-17
    相关资源
    最近更新 更多