SAP SuccessFactors 的 API 会因版本和类型的不同,返回不同格式的数据。核心的 API 包括标准的 OData API (主要返回 JSON 或 ATOM XML)以及传统的 SFAPI SOAP API(基于 XML)。
一 SuccessFactors集成涉及的一些名词解释
-
查询参数 (
$select, $expand, $filter):支持标准的 OData 查询方法来过滤、筛选和展开关联数据,满足不同获取数据的场景。 -
SAML & OAuth:支持通过 SAML 断言获取 OAuth 访问令牌的模式,用于安全地进行 API 调用。
-
Picklist 值 :查询时可以请求展开
picklistLabels导航属性,在响应中直接获取标签文本而非 ID,减少额外查询。 -
字段映射与布尔值 :集成时注意数据类型映射,尤其在与其他系统对接场景中,SuccessFactors 的布尔值 (
true/false) 可能会被转换为1/0。 -
Integration Center 配置 :可以在 Integration Center 通过界面化方式创建数据集成,并选择 XML 格式输出,降低配置难度。
-
Compound Employee API:一个 SOAP API,可用于通过单一请求检索一个或多个员工的完整或部分数据,通常通过 XPath 寻址来提取指定信息。
二 自定义CPI场景如何修改替换XML节点的值
2.1 方式一 xml.Content.toString().replace('Jane', '刘巍')
这里关键就是replace方法,可以替换节点或者节点属性值,例如下图中的context节点有个jane的关键子,我现在用刘巍替换jane。



Groovy
import com.sap.it.script.v2.api.Message
import groovy.xml.XmlSlurper
import groovy.xml.StreamingMarkupBuilder
def Message processData(Message message) {
// 1. CPI 强制要求:流式读取消息体(无报错)
def reader = message.getBody(java.io.Reader)
// 2. 用 XmlSlurper 解析(CPI 唯一推荐)
def xml = new XmlSlurper().parse(reader)
xml.Content = xml.Content.toString().replace('Jane', '刘巍')
// Serialize the modified XML
def updatedXml = groovy.xml.XmlUtil.serialize(xml)
message.setBody(updatedXml) // Set the modified XML as the message body
return message
}
Groovy
import com.sap.gateway.ip.core.customdev.util.Message;
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def messageLog = messageLogFactory.getMessageLog(message);
if(messageLog != null)
{
messageLog.setStringProperty("log2","formid")
messageLog.addAttachmentAsString("log2",body,"text/plain");
}
return message;
}

2.2 方式二 循环节点修改
第二种方式是每个循环每个节点,例如下图中有两个order的父节点,每个order节点下面有两个子节点status,现在我只是想替换第一个status节点的值。


Groovy
import com.sap.it.script.v2.api.Message
import groovy.xml.XmlParser
import groovy.xml.XmlNodePrinter
import java.io.StringWriter
def Message processData(Message message) {
// 1. 解析
def reader = message.getBody(Reader)
def root = new XmlParser().parse(reader)
// 2. 循环修改
root.order.each { order ->
// 找到 order 下的 status 节点
def statusNode = order.status[0] // status[0] 取第一个(因为可能多个同名)
if (statusNode) {
statusNode.value = 'completed' // 直接修改节点值
}
}
// 3. 将修改后的树写回
def writer = new StringWriter()
new XmlNodePrinter(new PrintWriter(writer)).print(root)
message.setBody(writer.toString())
return message
}
