【问题标题】:Datatype Map: Extract several atomic values数据类型映射:提取几个原子值
【发布时间】:2021-08-11 10:44:39
【问题描述】:

在从解析的 JSON 中提取数据时,我正在寻找“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]

【问题讨论】:

  • 当 JSON 有对象或 XDM 有映射而不是字符串或数字时,属性值的预期结果是什么?
  • 因此,当您的主题询问原子值时,问题是由在 XPath 中表示为映射的 JSON 对象 { "english": "hello", "spanish": "hola" } 引起的。目前尚不清楚您期望在那里进行什么样的默认处理。
  • 我想看看在从解析的 JSON 中提取数据时“parse-json”是否可以作为“json-to-xml”的一个选项,如果“parse-json”可以提取更多1 个值,使用“for-each”循环。更新了问题标题。
  • 嵌套对象或嵌套映射等层次结构通常不会由单个for-eachapply-templates 处理,您需要递归来处理任意嵌套。或者明确说明如何将嵌套映射序列化为单个属性值。
  • 我认为这是一个合理的答案。请将其移至答案,我会接受。只是希望对 JSON 解析的函数有一个清晰的了解。

标签: json xml xslt xslt-3.0


【解决方案1】:

嵌套对象或嵌套映射等层次结构通常不会由单个for-eachapply-templates 处理,您需要递归来处理任意嵌套。或者明确说明如何将嵌套映射序列化为单个属性值。

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

【讨论】:

  • 有递归搜索的map:find(),但是比较有限,我很少用。
  • @MichaelKay,是的,我考虑过,但是由于它递归地查找特定的键,我无法提出一个简单的建议将其放入问题中的for-each 示例中。
【解决方案2】:

这段代码有什么问题?

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2013-12-29
    • 1970-01-01
    • 2017-03-11
    相关资源
    最近更新 更多