简介
最近,我做了一个需求,以特定的XML格式将数据从S/4HANA发送到第三方系统。目标XML格式在其架构中不使用名称空间。由于数据是通过SOAP web服务从S/4HANA传输到CPI的,因此定制的ABAP服务使用者是从定制的WSDL生成的,这需要一个名称空间。
在CPI中,我必须对源有效负载执行一些操作,执行身份转换,并另外删除有效负载中的任何名称空间/前缀。
在CPI中如果将XMLAnonymizerBean添加到通道的模块处理器中,这将非常容易实现。然而,大数据需要学什么,在CPI中没有现成的功能。
尽管XSLT是一个自称的XSLT noob,但XSLT似乎是处理这种转换的一个明显选择。
因此,在花了一段时间在互联网论坛上搜索解决方案之后,使用Notepad++的XML工具插件笨拙地测试转换(我没有Altova或Oxygen XML!),我使用以下XSLT代码成功地实现了这个需求—万岁!
注意:这是一个简化版本,top返利,不适合XML负载中的注释或属性。
Groovy呢?
您可能知道,我更喜欢使用Groovy,人工智能书,所以我给自己一个挑战,看看是否可以在Groovy的基础上提出一个替代解决方案。理想情况下,服务器和云服务器,云计算和大数据的区别,它不仅应该解决我的特殊问题,即只从根节点删除名称空间,还应该解决整个XML负载,它需要某种形式的递归处理,类似于XSLT模板匹配。
核心概念
让我们看看在Groovy中实现需求所需的一些核心概念。
正如我前面提到的,在Groovy中使用XML很容易。特别是,如果我们想同时解析和更新XML负载,groovy.util.XmlParser语法分析器是个不错的选择。更多细节可以在我的博客文章场景2中找到,使用Groovy脚本轻松解析XML。下面几行显示了如何实例化解析器并访问解析的XML负载的根节点。
一旦我们可以访问XML负载的节点,我们将需要确定哪些节点包含名称空间前缀。这是通过检查groovy.util.Node节点是的实例groovy.xml.QName.
最后,最关键的部分是处理XML层次结构中的所有节点。这是通过递归算法实现的。
在Groovy中,这样的递归算法可以通过蹦床实现(Groovy有最为Groove的名字,不是吗!)Trampoline克服了方法递归调用自身太深时堆栈高度的限制。调用是连续进行的,因此避免了StackOverflowException。
下面是一个定义为Groovy闭包的递归函数的示例,然后是对它的调用。
将它放在一起
将所有组件放在一起,让我们看看它在CPI Groovy脚本中的样子。脚本中的步骤如下如下所示:-
解析XML负载从根节点开始处理XML负载将每个节点重新创建为不带命名空间前缀的节点对当前节点的子节点递归地重复步骤将修改后的XML序列化为输出
结论
在软件世界中,满足任何特定需求的方法不止一种。尽管Groovy脚本的结果并不像XSLT脚本那样紧凑,但我很高兴我把时间花在了挑战上。一路上我确实学到了一两件事,希望这有助于磨练我的常规技能,迎接未来的挑战