解析XML和JSON内容的一点技巧的实例代码分享

解析XML和JSON内容的一点技巧

概述

在没有统一标准的情况下,一个系统对接多个外部系统往往会遇到请求接口响应数据异构的情况,有可能返回的是xml,也有可能返回
json。除了返回类型不同,内容结构也不尽相同。以xml类型为例,
接口1返回内容

    16112638767472747178067    OK    200    ...

接口2返回内容

    16112638767472747178068    成功    1    ...

如果在我们系统中为每种格式的内容针对处理显然是不合理的,上面的内容中我们只是关心三种信息,分别是业务ID、状态值和描述信息,那么可不可以抽象这三种信息,
获得这些信息后再进行业务逻辑处理。

解析XML和JSON

根据业务抽象我们需要从XML或者JSON内容中获得三种信息,我们这里将会使用XPath和JSONPath的方式来解析。比如获得接口1的重要信息,
我们可以设定三个XPath表达式,

{    bid: "/root/bizKey",    code: "/root/returnCode",    description: "/root/returnMsg"}

bid,codedescription对应我们系统自己定义的字段名。
解析JSON内容也是同理的,只不过定义的是JSONPath表达式。

分两步走处理数据内容

假设我们从原始的XML和JSON数据中获得了bid,codedescription信息,
从接口1获得

{    bid: '16112638767472747178067',    code: '200',    description: 'OK'}

从接口2获得

{    bid: '16112638767472747178068',    code: '1',    description: '成功'}

假设我们从接口1文档获知状态值200表示请求成功,从接口2文档获知状态值1表示请求成功,虽然他们都表示请求成功,但是我们还是不能
把他们原原本本地保存到我们的业务相关表中(当然这些响应数据还是需要保存到另外的记录表中的,至少方便排查问题)。
假设我们的业务相关表是这样设计的

字段名 类型 描述

bidstring业务IDcodeint状态值,0=初始,1=请求中,2=成功,3=失败descriptionstring描述

因此,我们还必须定义规则把接口1返回的状态值200转换为我们系统的2,把接口2返回的状态值1转换为我们系统的2
总结一下,两步走解析XML和JSON数据内容

根据XPath或者JSONPath表达式解析获得重要信息

根据规则转换状态值

第一步解析数据获得重要信息

以XML为例,

public class XmlParseUtils {    private DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();    private XPathFactory xpathFactory = XPathFactory.newInstance();        /**     *      * @param param    数据内容     * @param paths 表达式     * @return     * @throws Exception     */    public Map parse(String param, Map paths) throws Exception{        InputSource inputSource = new InputSource(new StringReader(param));        Document document = dbFactory.newDocumentBuilder().parse(inputSource);        Map map = Maps.newHashMap();        for(String key : paths.keySet()) {            XPath xpath = xpathFactory.newXPath();            Node node = (Node) xpath.evaluate(paths.get(key), document, XPathConstants.NODE);            if(node == null) {                throw new Exception("node not found, xpath is " + paths.get(key));            }            map.put(key, node.getTextContent());        }        return map;    }}

parse函数的返回类型也可以是Map,暂且用Map

第二步根据规则转换状态值

这一步稍稍有点麻烦,不过我们先不考虑代码实现,反正你能想到的可能别人已经帮你实现了。首先我们根据接口文档定义规则,写出规则表达式(或者其他的什么),
又是表达式。假设接口1的返回的状态值比较简单,只有200表示成功,其他情况都是失败,那么我们可以这样定义规则,

code.equals("200") ? 2: 3

或者

23

亦或者

function handle(arg) {    if(arg == 200) {        return 2;    }    return 3;}handle(${code})

以上根据同一份文档定义了三种不同类型的状态值转换规则,肯定需要三种不同的实现。下面一一说明,

三目表达式

code.equals("200") ? 2: 3是一个三目表达式,我们将使用jexl引擎来解析,利用第一步解析数据获得重要信息的结果,我们可以这样做

    public Object evaluateByJexl(String expression, Map context) {        JexlEngine jexl = new JexlBuilder().create();        JexlExpression e = jexl.createExpression(expression);        JexlContext jc = new MapContext(context);        return e.evaluate(jc);    }

FreeMarker模板

23

处理这段模板我们可以这么做

    /**     *      * @param param FreeMarker模板     * @param context     * @return     * @throws Exception     */    public String render(String param, Map context) throws Exception {        Configuration cfg = new Configuration();        StringTemplateLoader stringLoader = new StringTemplateLoader();        stringLoader.putTemplate("myTemplate",param);        cfg.setTemplateLoader(stringLoader);        Template template = cfg.getTemplate("myTemplate","utf-8");        StringWriter writer = new StringWriter();        template.process(context, writer);        return writer.toString();    }

如果FreeMarker模板比较复杂,从模板预编译成Template可能会消耗更多的性能,就要考虑把Template缓存起来。

JavaScript代码段

function handle(arg) {    if(arg == 200) {        return 2;    }    return 3;}handle(${code})

这段js代码中存在${code},首先它需要使用FreeMarker渲染得到真正的handle方法的调用参数,然后

    public Object evaluate(String expression) throws Exception {        ScriptEngineManager manager = new ScriptEngineManager();        ScriptEngine engine = manager.getEngineByName("javascript");        return engine.eval(expression);    }

ScriptEngineManager的性能估计不太乐观,毕竟是一个语言的引擎。

不同转换规则实现的比较

类型 实现 优点 缺点

三目表达式Jexl简单(easy)简单(simple)FreeMarker模板FreeMarker—-JavaScript代码段FreeMarker + ScriptEngine直观过程复杂,性能问题

看起来Freemarker是一个不错的选择。
至此两步走小技巧已经实现了,都是利用了现成的代码实现。

或许我们会这样的挑战,在做状态值转换时需要知道当前系统某个业务状态值的情况,
此时Freemarker表达式可能是这样的,

223

这里我们可以使用Freemarker的特性,自定义Java函数或工具类,在模板中调用。

以上就是解析XML和JSON内容的一点技巧的实例代码分享的详细内容,更多请关注创想鸟其它相关文章!

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
在XML布局里给View设置点击事件的案例分享
上一篇 2025年12月17日 01:45:49
下一篇 2025年12月17日 01:46:06

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    700
  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    300
  • JavaScript函数中插入加载动画(Spinner)的正确方法

    本文旨在解决在JavaScript函数中插入加载动画(Spinner)时遇到的异步问题。通过引入async/await和Promise.all,确保在数据处理完成前后正确显示和隐藏加载动画,提升用户体验。我们将提供两种实现方案,并详细解释其原理和优势。 在Web开发中,当执行耗时操作时,显示加载动画…

    2026年5月10日
    500
  • Golang空接口如何应用在项目中

    空接口可用于接收任意类型值,常见于日志函数、通用数据结构、JSON动态解析及配置驱动逻辑,提升代码灵活性,但需配合类型断言确保安全,避免滥用以降低维护成本。 空接口 interface{} 在 Go 语言中是一个非常灵活的类型,它可以存储任何类型的值。虽然它牺牲了一部分类型安全,但在实际项目中合理使…

    2026年5月10日
    300
  • Golang使用Protobuf定义接口与消息格式

    Protobuf通过字段编号实现兼容性,新增字段可忽略、删除字段可保留编号,确保新旧版本互操作,支持服务独立演进。 在Golang项目中,利用Protobuf定义接口和消息格式,本质上是为服务间通信构建了一套高效、类型安全且跨语言的契约。它让数据结构清晰可见,RPC调用标准化,极大地简化了分布式系统…

    2026年5月10日
    000
  • Go语言接口与切片:如何识别和操作[]interface{}

    本文将深入探讨Go语言中如何识别和操作`[]interface{}`类型的切片。我们将介绍类型断言(Type Assertion)的关键作用,并通过`switch`语句演示如何安全地检测`[]interface{}`类型,并进而遍历其内部元素。文章旨在提供清晰的示例代码和专业指导,帮助开发者有效地处…

    2026年5月10日
    300
  • 从 JavaScript 获取 URL 并在 PHP DataGrid 中使用

    本文档旨在指导开发者如何从 JavaScript 函数中获取 URL,并将其动态应用于 PHP DataGrid。通过前端 JavaScript 动态生成 API 地址,并将其传递给后端的 PHP DataGrid,实现数据根据用户会话动态加载。 动态配置 DataGrid 的 URL 在构建动态 …

    2026年5月10日
    100
  • GolangWeb项目异常捕获与日志记录

    答案:通过中间件使用defer和recover捕获panic,结合zap等结构化日志库记录请求链路信息,为每个请求生成trace ID,实现异常捕获与可追踪日志,提升系统稳定性与可观测性。 在Go语言Web项目中,异常捕获与日志记录是保障系统稳定性和可维护性的关键环节。Go本身没有像其他语言那样的t…

    2026年5月10日
    100
  • JavaScript Electron桌面应用

    答案:使用JavaScript开发%ignore_a_1%桌面应用需结合Web技术与Node.js,通过主进程管理窗口、渲染进程展示界面,并利用IPC通信,调用系统功能如文件对话框,最后用electron-builder打包发布,注意安全与进程职责分离。 用JavaScript开发Electron桌…

    2026年5月10日
    100
  • Python代码如何实现定时任务 Python代码使用Schedule模块的配置

    答案:使用Python的schedule模块可实现定时任务,通过try-except处理异常确保程序不中断,结合threading实现多线程任务避免阻塞,利用JSON文件保存和加载任务配置实现持久化。 使用Python实现定时任务,主要依赖于schedule模块,它提供了一种简单易懂的方式来安排周期…

    2026年5月10日
    000
  • php代码如何操作JSON数据_php代码解析和生成JSON的方法

    答案:PHP中处理JSON需使用json_encode()和json_decode()函数。1、将数组转为JSON字符串时,用json_encode()并检查返回值是否为false;2、解析JSON字符串时,调用json_decode()并设第二参数为true返回数组,false则返回对象;3、处理…

    2026年5月10日
    000
  • JS注解怎么和TypeScript结合_ JS注解在TypeScript环境下的应用

    TypeScript 支持通过配置 allowJs 和 checkJs 在 JavaScript 文件中识别 JSDoc 注解并进行类型检查,可在混合项目中提升类型安全;常见用法包括 @type、@param、@returns 和 @typedef,能为变量、函数参数等提供类型信息,支持与 .ts …

    2026年5月10日
    000
  • Voyager 中关联关系的翻译问题解决方案

    本文档旨在解决在使用 TCGVoyager 管理后台时,关联模型无法正确翻译的问题。主要针对 Laravel 项目中,使用 Voyager 1.4 版本以及 Laravel 8.0 版本,并且已经配置多语言支持的情况下,如何确保关联关系中的可翻译字段能够根据当前应用语言环境进行正确翻译。通过修改 B…

    2026年5月10日
    000
  • Go语言与Microsoft SharePoint集成指南

    Go语言可以有效集成Microsoft SharePoint,主要通过两种途径:一是利用SharePoint提供的RESTful API进行数据交互,Go的标准HTTP客户端库即可轻松实现;二是通过SharePoint应用模型开发自托管应用,这种模型支持使用包括Go在内的任何语言编写后端逻辑。 1.…

    2026年5月10日
    000
  • 如何安全有效地从外部网页获取HTML元素数据并应用于自身页面

    本教程旨在解决如何在不同域名下,通过javascript获取并使用另一个网页的html元素数据。文章将深入探讨同源策略的限制,并提供两种主要解决方案:使用` 在现代Web开发中,有时我们需要从外部网站获取特定的HTML内容或属性值,并将其整合到我们自己的网页中。例如,从XYZ.COM/B.html页…

    2026年5月10日
    100
  • 解决PHP foreach循环中变量“继承”问题:理解与避免意外数据泄露

    本文探讨PHP foreach循环中一个常见的陷阱:当循环内部的数组或变量未被显式初始化时,其值可能会“继承”自上一次循环迭代,导致意外的数据泄露和逻辑错误。文章将深入分析这一现象的根源,并通过示例代码展示如何通过在每次迭代开始时正确初始化变量来解决此问题,确保代码行为的预期一致性。 引言:fore…

    2026年5月10日
    100
  • 如何在不暴露密钥的情况下,在客户端创建 Stripe Payment Link

    本文介绍了在纯静态网站环境下,如何利用 Stripe Payment Link 实现商品售卖,并着重讨论了在不暴露 Stripe 密钥的前提下,客户端创建 Payment Link 的可行性。分析了直接在客户端使用密钥的风险,并提出了预先生成 Payment Link 或使用后端服务动态生成 Pay…

    2026年5月10日
    000
  • ChromaDB向量嵌入的有效持久化策略

    本文详细介绍了如何利用langchain中chromadb的`persist_directory`功能,高效地持久化存储向量嵌入。通过将生成的嵌入数据保存到本地磁盘,可以有效避免重复计算,显著提升工作流程效率。教程将涵盖持久化chromadb实例的创建与后续加载的完整过程。 在处理大规模文本数据并生…

    2026年5月10日
    000
  • 解决Go语言中GOPATH未设置错误及工作区配置指南

    本文旨在解决go语言开发中常见的“gopath not set”错误,并提供详细的go工作区配置指南。内容涵盖`gopath`环境变量的设置、go项目目录结构、`path`变量的扩展,以及一些高级配置技巧,旨在帮助开发者建立一个高效、规范的go开发环境,确保包的下载、编译和运行顺利进行。 Go语言在…

    2026年5月10日
    000
  • html函数如何实现动态内容显示 html函数在网页交互中的核心应用

    JavaScript函数通过操作DOM实现动态内容更新与交互,如显示时间、实时搜索、增删元素及加载数据,使网页具备动态功能。 HTML 本身没有“函数”的概念,它是一种标记语言,用于定义网页结构。真正实现动态内容显示和交互功能的是 JavaScript。通常所说的“HTML函数”其实是 JavaSc…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信