数据类型映射:提取几个原子值

Datatype Map: Extract several atomic values

我想看看在从已解析的 [=35] 中提取数据时,“parse-json”是否可以作为“json-to-xml”的选项=] 如果“parse-json”可以提取超过 1 个值,则使用“for-each”循环。

JSON 文件:

<data>
{
    "weather": "Sunny",
    "greetings": {
      "english": "hello",
      "spanish": "hola"
    }
  }
</data>

XSL:

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

<xsl:transform
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:root="http://www.example.org/0"
  xmlns:wheather="http://www.example.org/1"
  xmlns:greetings="http://www.example.org/2"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
  expand-text="yes">

  <xsl:output method="xml" indent="yes"/>

  <!-- Test [1] Extract single value using "parse-json" -->

  <!-- <xsl:template match="data">
    <root:report>
      <xsl:variable name="json" select="parse-json(.)"/>
      <greetings:test>{$json?weather}</greetings:test>
    </root:report>
  </xsl:template> -->

  <!-- Test [2] Extract many value using "parse-json" -->

  <xsl:template match="data">
    <xsl:variable name="map" select="parse-json(.)"/>
    <xsl:for-each select="map:keys($map)">
      <entry key="{.}" value="{$map(.)}"/>
    </xsl:for-each>
  </xsl:template>

</xsl:transform>

结果

空白/无

错误

Saxon-HE 10.5J from Saxonica
Java version 11.0.11
Stylesheet compilation time: 350.912306ms
Processing file:[Xxx]
Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
Building tree for file:[Xxx] using class net.sf.saxon.tree.tiny.TinyBuilder
Error in entry/@value on line 28 column 43 of principal.xsl:
  FOTY0013  Cannot atomize a map (map{"spanish":"hola","english":"hello"})
     invoked by xsl:for-each at file:[Xxx]
  In template rule with match="data" on line 25 of principal.xsl
     invoked by built-in template rule (text-only)
Cannot atomize a map (map{"spanish":"hola","english":"hello"})
[Finished in 0.879s]

像嵌套对象或嵌套映射这样的层次结构通常不会被单个for-eachapply-templates处理,您需要递归来处理任意嵌套。或者关于如何将嵌套映射序列化为单个属性值的清晰描述。

当然,在使用例如 XPath 导航的情况下//descendant 您可以轻松处理和展平层次结构。没有类似的通过XDM maps的hierarchy向下选择;它可以使用 map:for-each 和递归来实现。

这段代码有什么问题?

<xsl:for-each select="map:keys($map)">
  <entry key="{.}" value="{$map(.)}"/>
</xsl:for-each>

它试图处理映射中的所有条目,但使用 "{$map(.)}" 意味着它仅适用于可以表示为原子值的条目 - 也就是说,它对映射条目无效.如果你想让你的代码保持通用,那么你需要在决定如何处理它之前使用 instance-of 测试 $map(.) 的类型。或者,您可以使用 serialize() 函数以 JSON 格式显示每个值 - 但这取决于您要实现的目标。