跳到主要内容
← 返回博客

本文涉及的模块: Integration Flow Helper

根据示例负载编写 SAP CPI XPath:XML 以及 JSON 转 XML

根据示例负载为 SAP CPI 的 Content Modifier、Router、Filter 和 Splitter 编写 XPath:XML 路径、命名空间,以及经由 JSON to XML Converter 根元素处理 JSON。

根据示例负载编写 SAP CPI XPath:XML 以及 JSON 转 XML

XPath 是 SAP CPI 从 XML 消息中读取值的方式:为属性读取订单号,为 Router 条件读取状态,为 Splitter 选取重复节点。最快写对 XPath 的方法,是从真实的负载样本出发,而不是从接口说明出发。

本文介绍 XPath 在 iFlow 中的使用位置、如何从 XML 样本推导路径、命名空间如何工作,以及 JSON 负载如何转换为 XML,包括为什么它们的路径以 /root 开头。

XPath 在 iFlow 中的使用位置

  • Content Modifier:源类型为 XPath 的 header 行或属性行从消息体中读取值。数据类型决定你得到的是文本(例如 java.lang.String)还是节点。
  • Router 和 Filter:类型为 XML 的条件是 XPath 表达式,例如 /Orders/Order/Status = 'OPEN'。
  • Splitter:XPath 表达式选取重复节点,每个节点生成一条消息。
  • Gather、Aggregator 和 Content Enricher:XPath 指向要合并、关联或扩充的节点。

它们都作用于该步骤时的消息体。经过映射或转换器之后,路径会随结构一起变化。

从 XML 样本到 XPath

下面是一个包含两个订单的小样本:

<Orders>
  <Order status="OPEN">
    <Id>4711</Id>
    <Customer id="C-100">ACME</Customer>
    <Amount currency="EUR">1250.00</Amount>
  </Order>
  <Order status="CLOSED">
    <Id>4712</Id>
    <Customer id="C-200">Globex</Customer>
    <Amount currency="EUR">80.00</Amount>
  </Order>
</Orders>
XPath在样本上的结果
/Orders/Order/Id所有订单 ID:4711 和 4712
/Orders/Order[@status='OPEN']/Id未结订单的 ID:4711
/Orders/Order[1]/Customer/@id第一个订单的客户 ID:C-100
count(/Orders/Order)订单数量:2
/Orders/Order[Amount > 1000]金额超过 1000 的订单

以 / 开头的路径从根开始;//Id 会在任意位置查找 Id 元素,虽然方便,但在大型负载上更慢。

命名空间

如果负载中的元素位于某个命名空间中,不带前缀的路径将什么也找不到。请在 iFlow 的 Runtime Configuration 中的 Namespace Mapping 里为每个命名空间声明一个前缀,格式为 xmlns:ord=http://example.com/orders,并在每一步中使用它:/ord:Orders/ord:Order/ord:Id。

你映射中的前缀不必与负载中的前缀相同,只需命名空间 URI 一致即可。如果 XPath 在一个你看得清清楚楚的负载上什么也返回不了,通常是缺少了 Namespace Mapping。

JSON 负载:经由 JSON to XML Converter 使用 XPath

XPath 作用于 XML,因此 JSON 消息需要先用 JSON to XML Converter 转换。包含多个成员的 JSON 对象没有唯一的根元素,所以转换器的 Add XML Root Element 选项会用一个根元素把它包起来,默认名为 root。路径因此以 /root 开头,数组中的每一项都会变成一个以数组名命名的重复元素:

{
  "orderId": "4711",
  "customer": { "id": "C-100", "name": "ACME" },
  "items": [
    { "sku": "A-1", "qty": 2 },
    { "sku": "B-7", "qty": 1 }
  ]
}

JSON to XML Converter (root element: root)

<root>
  <orderId>4711</orderId>
  <customer><id>C-100</id><name>ACME</name></customer>
  <items><sku>A-1</sku><qty>2</qty></items>
  <items><sku>B-7</sku><qty>1</qty></items>
</root>

/root/orderId              4711
/root/customer/name        ACME
/root/items/sku            A-1, B-7
/root/items[qty > 1]/sku   A-1

如果你在转换器中给根元素起了别的名字,请相应修改每条路径的第一步。在 XPath 步骤之后要转回 JSON,请使用 XML to JSON Converter。

为什么 XPath 什么也不返回

  • 命名空间未在 Namespace Mapping 中声明,或路径缺少前缀。
  • 大小写错误:在 XPath 中,元素名和 XML 属性(attribute)名区分大小写。
  • 路径是针对映射或转换器修改之前的负载编写的。
  • JSON 路径缺少 /root 这一步,或者在根元素改名之后仍使用默认名称。
  • Content Modifier 行的数据类型错误:java.lang.String 返回文本,org.w3c.dom.NodeList 返回节点。

接下来要把这些值拼进消息体?Simple 表达式文章介绍了如何使用刚刚读取的属性,Postman 和 OpenAPI 文章则介绍了如何把 JSON 请求体发送给 REST API。

Kitegra 如何帮你

浏览器扩展 Kitegra 会根据你的样本写出路径。向它提供 XML 或 JSON 示例负载,它就会在 Content Modifier 的 XPath 行以及 Router、Filter、Splitter、Gather、Aggregator 和 Content Enricher 中提示 XPath 表达式。对于 JSON 样本,提示的路径从转换器的根元素 /root 开始。

示例负载只保留在你的浏览器中:Kitegra 从不保存它们。它从不保存、部署或编辑 iFlow 的内容;只有在你点击四个指定操作之一时,tenant 才会发生变化,而且这些操作可以关闭。

要查看 XPath 步骤实际收到的消息体,请逐步跟踪消息。

没有 Kitegra 账户时,每个模块可用于 5 个 iFlow。Free 套餐涵盖 50 个,Starter 100 个,Pro 300 个;Business 不限。比较各套餐。

在下一个 iFlow 中试试

了解 Kitegra 在 SAP Integration Suite 设计器中能做什么,或在 Kitegra 的其他 Chrome 扩展旁查看它。

常见问题

在 SAP CPI 中如何把 XML 中的值读取到属性里?

在 Content Modifier 中添加一行 exchange property,源类型选 XPath,源值填写路径(例如 /Orders/Order/Id),数据类型选 java.lang.String。

为什么我的 XPath 什么也不返回?

最常见的原因是命名空间未在 Namespace Mapping 中声明、元素名大小写错误,或者路径是针对映射修改之前的负载编写的。

可以对 JSON 负载使用 XPath 吗?

不能直接使用。请先用 JSON to XML Converter 转换 JSON,再针对转换后的 XML 编写 XPath。

为什么 JSON 的 XPath 以 /root 开头?

JSON to XML Converter 默认会添加一个名为 root 的根元素,因为包含多个成员的 JSON 对象没有唯一的根。如果你给它改了名,请相应修改路径。

JSON 数组经过 JSON to XML Converter 之后是什么样子?

数组的每一项都会变成一个以数组名命名的重复元素,因此包含两项的 items 会变成两个 items 元素,用 /root/items 读取。

如何用 XPath 按订单拆分消息?

使用 Splitter,并填写重复节点的 XPath,例如 /Orders/Order。每个订单都会成为一条独立的消息。

无需离开设计器即可处理 iFlow

将 Kitegra 添加到 Chrome 或 Microsoft Edge。免费开始,无需账户。