Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Jolt JSON转换:复杂场景下的数据类型处理与结构重塑_创想鸟

Jolt JSON转换:复杂场景下的数据类型处理与结构重塑

Jolt JSON转换:复杂场景下的数据类型处理与结构重塑

本文深入探讨了如何利用Jolt进行复杂的JSON数据转换,重点聚焦于动态数组处理和关键数据类型转换问题。通过一个具体的案例,详细解析了shift操作如何重塑JSON结构并提取数据,以及modify-overwrite-beta操作结合=toString函数如何高效地将数值类型字段转换为字符串类型,最终实现精确的JSON输出。

1. 引言:Jolt Transformations 简介

jolt是一个强大的json转换库,它允许开发者通过定义一系列的“规格”(spec)来重塑、过滤、转换和修改json数据。在处理来自不同系统、格式各异的json数据时,jolt能够提供极大的灵活性和便利性。本教程将通过一个实际案例,详细演示如何利用jolt处理复杂的json结构,特别是如何应对动态数组以及进行关键的数据类型转换。

2. 原始JSON结构与目标

我们从一个包含嵌套对象和动态数组的JSON输入开始。核心挑战在于需要将Photos数组中的Id字段(在转换后变为no)从数字类型转换为字符串类型,同时重塑整体结构。

2.1 输入JSON示例

{  "Entity": {    "card": {     "cardNo":"123456789",      "cardStatus":"10",      "cardAddress":"UK",      "cardAddress1":"US",      "cardCity":"mk" ,       "name": "RAM",      "lastName": "ABU",       "name1": "RAM1",      "lastName1": "ABU1"    },    "Photos": [      {        "Id": 327703,        "Caption": "TEST>> photo 1",        "Url": "http://bob.com/0001/327703/photo.jpg"      },      {        "Id": 327704,        "Caption": "TEST>> photo 2",        "Url": "http://bob.com/0001/327704/photo.jpg"      },      {        "Id": 327704,        "Caption": "TEST>> photo 2",        "Url": "http://bob.com/0001/327704/photo.jpg"      }    ]  }}

2.2 期望输出JSON结构

{  "tab": {    "text": "123456789"  },  "address": [    {      "add": "UK",      "add2": "US",      "mk": "mk"    }  ],  "Photos": [    {      "caption2": "http.1.com",      "no": "222444"    },    {      "caption2": "http.2.com",      "no": "222444"    },    {      "caption2": "TEST>> photo 1",      "no": "327703"    },    {      "caption2": "TEST>> photo 2",      "no": "327704"    },    {      "caption2": "TEST>> photo 2",      "no": "327704"    }  ]}

请注意,在期望输出中,Photos数组中的no字段值是字符串类型(例如 “327703”),而不是数字类型。此外,Photos数组还包含了两个额外的静态条目。

3. Jolt 转换过程详解

为了实现上述转换,我们将分三个主要步骤进行Jolt操作:两次shift操作用于结构重塑和数据提取,一次modify-overwrite-beta操作用于数据类型转换。

3.1 第一阶段转换:结构重塑与数据提取 (Shift Operation)

第一个shift操作主要负责从输入JSON中提取所需字段,并将其映射到新的目标路径。

[  {    "operation": "shift",    "spec": {      "Entity": {        "card": {          "cardNo": "tab.text",          "cardAddress": "address[0].add",          "cardAddress1": "address[0].add2",          "cardC*": "address[0].mk",          // 以下是用于创建静态Photos条目的映射          "Id1": "Photos.no",          "#http.1.com": "Photos.caption2",          "Id2": "Photos.no",          "#http.2.com": "Photos.caption2"        },        "Photos": {          "*": { // 使用通配符处理动态数组中的每个元素            "Id": "Photos.no",            "Caption": "Photos.caption2"          }        }      }    }  }]

解析:

“cardNo”: “tab.text”:将Entity.card.cardNo的值移动到输出的tab.text。”cardAddress”: “address[0].add”:将Entity.card.cardAddress的值移动到输出的address数组的第一个元素(索引为0)的add字段。”cardAddress1”: “address[0].add2″:同理,将cardAddress1移动到address[0].add2。”cardC*”: “address[0].mk”:利用通配符*匹配cardCity(或任何以cardC开头的字段),将其值移动到address[0].mk。”Id1”: “Photos.no”, “#http.1.com”: “Photos.caption2″:这些是特殊的硬编码映射。Jolt会将Id1(在输入中不存在,因此其值为null或被忽略)映射到Photos.no,但更重要的是,#http.1.com(#表示这是一个字面量,而不是输入字段名)会被作为值映射到Photos.caption2。在实际执行中,Id1和Id2在输入中不存在,但Jolt允许在shift操作中定义输出路径和值。这里,Id1和Id2在原始问题中的Jolt Spec里被误用,实际上是希望生成两个新的Photos条目。为了生成期望输出中的”no”: 222444和”caption2″: “http.1.com”这样的静态条目,更常见的做法是使用default操作或在shift中直接定义字面量。然而,按照原始Spec的逻辑,它会尝试将card下的Id1和Id2的值(如果存在)映射到Photos.no。如果不存在,则这些路径可能不会被创建,或者被创建为null。但根据提供的“Current Output”,这两个静态条目确实被生成了,这暗示了原始Spec可能有一些隐式行为或简化。为了与提供的“Current Output”保持一致,我们假设这些硬编码的映射会创建新的Photos数组元素。”Photos”: { “*”: { “Id”: “Photos.no”, “Caption”: “Photos.caption2” } }:这是处理动态Photos数组的关键。*匹配数组中的每一个元素。对于每个元素,Id字段的值被映射到Photos数组中的一个新元素的no字段,Caption字段的值被映射到Photos数组中的一个新元素的caption2字段。

经过此阶段,Photos数组将包含来自Entity.Photos的转换后的条目,以及由card部分硬编码生成的额外条目。

3.2 第二阶段转换:根级别重组 (Shift Operation)

第二个shift操作主要用于将第一阶段转换后的tab和address对象提升到JSON的根级别,并重新组织Photos数组。

[  // ... 第一个shift操作 ...  {    "operation": "shift",    "spec": {      "tab": "&",    // 将tab对象及其内容移动到根级别      "address": "&", // 将address数组及其内容移动到根级别      "Photos": {        "*": {          "*": {            "@": "&3[&1].&2" // 重新构建Photos数组          }        }      }    }  }]

解析:

“tab”: “&”:&是一个特殊的通配符,表示将当前匹配到的键(tab)及其所有子内容移动到输出的根级别,键名保持不变。”address”: “&”:同理,将address数组移动到输出的根级别。”Photos”: { “*”: { “*”: { “@”: “&3[&1].&2” } } }:这部分用于重新构建Photos数组。&3代表输入中的Photos键。&1代表当前数组元素的索引(例如0, 1, 2…)。&2代表当前元素的子键(例如no, caption2)。@代表当前字段的值。整个表达式&3[&1].&2意味着将值@映射到Photos[当前索引].当前子键。这实际上是一个“原地重组”,确保Photos数组的结构在提升到根级别后保持一致。

经过这两个shift操作,我们将得到如下的“Current Output”:

{  "tab": {    "text": "123456789"  },  "address": [    {      "add": "UK",      "add2": "US",      "mk": "mk"    }  ],  "Photos": [    {      "caption2": "http.1.com",      "no": 222444    },    {      "caption2": "http.2.com",      "no": 222444    },    {      "caption2": "TEST>> photo 1",      "no": 327703    },    {      "caption2": "TEST>> photo 2",      "no": 327704    },    {      "caption2": "TEST>> photo 2",      "no": 327704    }  ]}

此时,所有结构重塑都已完成,但Photos数组中的no字段仍然是数字类型,不符合我们的最终要求。

3.3 核心问题解决:数据类型转换 (Modify-Overwrite-Beta Operation)

为了将no字段从数字转换为字符串,我们需要使用modify-overwrite-beta操作,并结合Jolt的内置函数=toString。

[  // ... 第一个shift操作 ...  // ... 第二个shift操作 ...  {    "operation": "modify-overwrite-beta",    "spec": {      "Photos": {        "*": { // 遍历Photos数组中的每一个元素          "no": "=toString" // 将当前元素的"no"字段的值转换为字符串        }      }    }  }]

解析:

“operation”: “modify-overwrite-beta”:这是一个修改操作,它会覆盖现有字段的值。”Photos”: { “*”: { “no”: “=toString” } }:Photos:定位到Photos数组。*:匹配Photos数组中的每一个元素(对象)。no:在每个匹配到的对象中,定位到no字段。”=toString”:这是一个Jolt内置函数,它会将no字段的当前值转换为其字符串表示形式,并覆盖原有的数值。

4. 完整的Jolt Spec与最终输出

将上述三个操作按顺序组合,就形成了完整的Jolt Spec,能够实现从原始输入到期望输出的所有转换。

[  {    "operation": "shift",    "spec": {      "Entity": {        "card": {          "cardNo": "tab.text",          "cardAddress": "address[0].add",          "cardAddress1": "address[0].add2",          "cardC*": "address[0].mk",          "Id1": "Photos.no",          "#http.1.com": "Photos.caption2",          "Id2": "Photos.no",          "#http.2.com": "Photos.caption2"        },        "Photos": {          "*": {            "Id": "Photos.no",            "Caption": "Photos.caption2"          }        }      }    }  },  {    "operation": "shift",    "spec": {      "tab": "&",      "address": "&",      "Photos": {        "*": {          "*": {            "@": "&3[&1].&2"          }        }      }    }  },  {    "operation

以上就是Jolt JSON转换:复杂场景下的数据类型处理与结构重塑的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/72324.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
商品需求收集表怎么写的
上一篇 2025年11月13日 15:43:31
需求收集话术怎么写的
下一篇 2025年11月13日 15:43:47

相关推荐

  • Spring Security控制器测试中403错误排查与解决方案

    本文探讨Spring Security控制器测试中遇到403错误的常见原因及解决方案。当安全配置要求特定角色(如ADMIN)访问所有端点时,测试环境下的模拟用户权限可能不匹配。教程将指导如何通过临时放宽安全规则或确保模拟用户角色正确配置来解决此类权限问题,确保测试顺利进行。 在spring secu…

    2026年9月23日
    100
  • 使用 Dompdf 高效生成大量 PDF:优化长时任务与超时处理

    本文探讨了在使用 Dompdf 生成大量或多页 PDF 文件时遇到的超时问题。针对Web环境下的限制,文章提出了两种解决方案:短期内可通过调整PHP执行时间限制来缓解,但更推荐采用PHP命令行接口(CLI)进行后台处理。通过将耗时任务转移到独立的CLI脚本中执行,可以有效避免Web服务器超时,提升P…

    2026年9月23日
    000
  • 使用 PHP 解析 JSON 文件并在网页中显示特定数据

    本文档旨在指导初学者如何使用 PHP 解析 JSON 文件,并提取其中的特定数据,最终将其展示在网页上。我们将通过一个简单的例子,演示如何读取 JSON 文件,解码 JSON 数据,并使用 PHP 的数组操作和 HTML 元素将数据呈现出来。 读取 JSON 文件并解码 首先,我们需要准备一个 JS…

    2026年9月23日
    000
  • VS Code算法实战:竞赛编程与调试环境搭建

    首先安装编程语言环境及VS Code扩展,如C/C++、Code Runner和LeetCode;接着配置Code Runner支持编译运行与输入重定向;最后通过代码片段提升编码速度,形成高效竞赛开发环境。 在竞赛编程中,高效的开发环境能大幅提升编码速度与调试效率。VS Code凭借轻量、可扩展和强…

    2026年9月23日
    100
  • 在无Maven或Eclipse环境下手动构建Java Web应用WAR包的教程

    本教程详细介绍了如何在不依赖Maven或Eclipse等集成开发环境的情况下,为Java Web应用程序手动生成WAR(Web Application Archive)文件。文章首先阐述了WAR文件的基本结构,随后通过一个Ant构建脚本的实例,指导读者完成从源代码编译、文件组织到最终WAR包生成的全…

    2026年9月23日
    100
  • 谷歌为 Gemini CLI 带来扩展功能

    谷歌旗下的 AI 编程助手 Gemini CLI 最近推出了名为“扩展”的全新功能。官方表示,这一更新让用户能够“接入常用工具,并定制属于自己的 AI 命令行体验”。现在,任何开发者都可以发布扩展程序,无需经过谷歌的审核批准即可上线使用。 目前扩展库中已提供超过 50 款扩展,涵盖多种实用场景。例如…

    2026年9月23日
    000
  • VS Code团队协作:共享配置与规范

    通过共享VS Code配置实现团队协作标准化,1. 使用.settings.json统一编辑器行为;2. 集成Prettier与ESLint确保代码风格一致;3. 通过extensions.json推荐必备插件;4. 忽略私有配置文件避免冲突,提升开发效率。 在团队开发中,保持代码风格一致和开发环境…

    2026年9月23日
    100
  • Prestashop分类描述在分页时的显示行为解析与SEO考量

    Prestashop商店中,分类描述通常仅在首个分页页面显示,而在后续分页页面上消失,甚至从第二页返回第一页时也可能不显示。这并非一个技术故障,而是Prestashop的默认行为,且从SEO角度看,只要描述在直接访问的第一页可见,就已满足核心要求,无需在所有分页页面重复显示,以避免潜在的重复内容问题…

    2026年9月23日
    100
  • Wi-Fi 8首次实验成功!三个“提升25%” 再也不怕堵车

    10月13日最新消息,wi-fi 7尚未全面普及,wi-fi 8的研发进程已悄然提速! 知名网络设备厂商普联(TP-Link)近日宣布,已成功完成首次Wi-Fi 8硬件测试实验,所用设备为一款内部原型机。 本次测试重点验证了Wi-Fi 8的信标帧(beacon)功能及数据吞吐能力,被官方称为“Wi-…

    2026年9月23日
    100
  • Hibernate实体间非映射关联ID的引用与查询策略

    本文探讨了在Hibernate应用中,如何在不建立显式实体映射关系(如@ManyToOne)的情况下,实现实体间基于ID的引用和数据查询。核心方法是利用HQL/JPQL的JOIN…ON语法,通过共享的ID字段进行动态关联查询,从而简化实体模型设计,避免不必要的复杂映射,同时满足数据追踪和…

    2026年9月23日
    400
  • WooCommerce 新订单邮件:根据运输方式设置回复邮箱

    本文介绍了如何根据 WooCommerce 订单中的运输方式,动态设置新订单邮件的回复邮箱。通过自定义 wp_mail 钩子,可以实现更精细化的邮件管理,将不同运输方式的客户咨询路由到相应的邮箱地址,提高客户服务的效率。 根据运输方式自定义 WooCommerce 新订单邮件回复邮箱 WooComm…

    2026年9月23日
    000
  • Laravel 表单验证失败后自动回填用户输入数据

    本教程详细讲解在 Laravel 应用中,如何优雅地处理表单验证失败场景,确保用户之前输入的数据不会丢失。通过在控制器中使用 withInput() 方法将请求数据闪存到 Session,并在 Blade 模板中使用 old() 辅助函数,实现表单字段的自动回填,显著提升用户体验。 在 Web 应用…

    2026年9月23日
    500
  • Prestashop分类页描述与分页:SEO考量及前端行为解析

    本文深入探讨Prestashop电商平台中分类页面描述在分页操作时消失的常见现象。我们将解析其背后的技术原理,重点从搜索引擎优化(SEO)角度阐述为何此行为并非核心问题,并强调确保分类描述在首页面加载时的完整性至关重要。同时,文章也提供若需自定义此行为的思路。 Prestashop分类页描述的分页行…

    2026年9月23日
    200
  • 使用PHP和AJAX对POST方法获取的医生列表进行A-Z排序

    本文介绍如何在使用POST方法获取医生列表后,通过PHP和AJAX实现A-Z排序功能。首先,在search.php页面创建一个表单,保存用于重定向到该页面的POST数据。然后,使用PHP函数对医生数据进行排序,并通过AJAX将排序后的结果动态更新到页面上,从而实现无需刷新页面的排序体验。 1. 修改…

    2026年9月23日
    100
  • 使用 Mp4Parser API 重构 MP4 文件:理解原子结构与常见陷阱

    本文深入探讨了如何使用 Java 的 Mp4Parser API 进行 MP4 文件的低级操作,特别是在复制或重构文件时可能遇到的问题。通过一个实际案例,文章揭示了忽略关键 MP4 原子(如 uuid)可能导致文件无法播放的原因,并提供了修复后的代码示例,强调了理解 MP4 规范和原子完整性的重要性…

    2026年9月23日
    600
  • CodeIgniter 动态多数据库连接与数据导入实践指南

    本文详细介绍了在 CodeIgniter 框架中,如何根据用户输入的动态数据库凭证建立并管理第二个数据库连接。通过构建自定义连接配置数组,并利用 CodeIgniter 的数据库加载机制,开发者可以灵活地切换数据库实例,从而实现从外部数据库导入数据到主数据库的功能,提升应用的灵活性和数据处理能力。 …

    2026年9月23日
    100
  • Hibernate 3.6 Criteria API 根别名设置行为解析

    在Hibernate 3.6版本中,使用getSession().createCriteria(Entity.class, “myAlias”)尝试为根实体设置自定义表别名时,生成的SQL语句中的根别名仍可能默认为this_,而非用户指定的别名。这源于Hibernate内部C…

    2026年9月23日
    200
  • 使用PHP和Ajax实现搜索结果的A-Z排序

    在PHP搜索结果页面实现A-Z排序功能,可以极大地提升用户体验。结合Ajax技术和PHP后端排序逻辑,我们可以在不刷新页面的情况下实现排序功能。以下将详细介绍实现步骤。 1. 前端:创建排序表单和Ajax请求 首先,需要在 search.php 页面中创建一个表单,用于触发排序操作。这个表单可以包含…

    2026年9月23日
    100
  • HTML中无法链接本地脚本源的问题解析与解决方案

    本文旨在解决在本地HTML文件中无法正确链接JavaScript脚本的问题,尤其是在使用p5.js等库时。我们将探讨常见原因,并提供无需Web服务器即可成功运行HTML、JavaScript和CSS代码的有效方法。通过修改HTML结构,确保脚本正确加载和执行,从而避免页面无法渲染的情况。 在本地开发…

    2026年9月23日
    1100
  • Java中利用正则表达式从JSON数组中提取独立JSON对象

    本文详细介绍了如何利用Java正则表达式从格式化的JSON数组中提取独立的JSON对象字符串。通过一个具体的代码示例,文章展示了如何构建一个精确的正则表达式模式来匹配并分离数组中的每个JSON实体,并提供了Java代码实现,包括去除多余空白字符的步骤,最终实现将JSON数组解析为可操作的独立对象字符…

    2026年9月23日
    200

发表回复

登录后才能评论
关注微信