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

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。每个订单都会成为一条独立的消息。