Groovy 脚本 - 员工报告结构 - 循环 XML 以找到所需的领导者
Groovy Script - Employee reporting structure - Looping through XML to find required Leader
我有两个 xml 使用 <multimap>
节点组合在一起。第一个数据源发送员工和经理 ID 信息(节点),第二个数据源发送所有领导者 ID 信息(节点中仅列出领导者 ID,领导者可以是经理的经理或直接经理或 2-up/3-up )它们都组合在<multimap>
标签。
我想遍历 <multimap1>
节点的 <PerPerson>
,检查经理 ID,直到在 中找到领导者 ID,一旦找到领导者 ID,就在员工记录(节点)中添加一个节点。
请帮忙!
XML 文件:
<?xml version='1.0' encoding='UTF-8'?>
<multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
<multimap:Message1>
<PerPerson>
<PerPerson>
<empId>12345</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67891</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
<PerPerson>
<empId>67891</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
<PerPerson>
<empId>56789</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
<PerPerson>
<empId>12123</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67678</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
</PerPerson>
</multimap:Message1>
<multimap:Message2>
<rfc:ZZH_LEADER_WF_GET_APPROVERS.Response xmlns:rfc="urn:sap-com:document:sap:rfc:functions">
<LEADER>12123</LEADER>
<LEADER>23234</LEADER>
<LEADER>34345</LEADER>
<LEADER>56567</LEADER>
<LEADER>67678</LEADER>
</rfc:ZZH_LEADER_WF_GET_APPROVERS.Response>
</multimap:Message2>
</multimap:Messages>
所需结果:在上面的员工和经理数据中,在标签内进行迭代,直到经理 ID 是 rfc / get approvers 列表中的领导者 ID 之一。一旦找到,在标签内添加带有 ID 的领导者 ID 标签
<?xml version='1.0' encoding='UTF-8'?>
<PerPerson>
<PerPerson>
<empId>12345</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67891</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>12123<leader>
</PerPerson>
<PerPerson>
<empId>67891</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>12123<leader>
</PerPerson>
<PerPerson>
<empId>56789</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>12123<leader>
</PerPerson>
<PerPerson>
<empId>12123</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67678</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>67678<leader>
</PerPerson>
</PerPerson>
我试过的代码
map = message.getProperties();
def body = message.getBody(java.lang.String) as String;
def messageLog = messageLogFactory.getMessageLog(message);
def xml = new XmlParser().parseText(body)
def ns = new groovy.xml.Namespace('http://sap.com/xi/XI/SplitAndMerge')
def rfcNs = new groovy.xml.Namespace('urn:sap-com:document:sap:rfc:functions')
//for fast search let map PERNR value to a node that contains it, like internal table
def leaderMap = xml[ns.Message1][0][rfcNs.get("ZHR_GET_AWARD_LEADERS.Response")][0].children().collectEntries{ [it.LEADER_LIST.item.text().replaceFirst("^0+(?!$)", ""), it] }
//itearte msg1 -> find entry in leaderMap -> add node
xml[ns.Message2][0].PerPerson[0].each{p->
def emp = p.PerPerson[0]
def leader = leaderMap[p.PerPerson.userAccountNav.UserAccount.user.User.manager.User.mgrEmpId.text()]
if(leader)
{
// def counter = counter + 1
p.PerPerson.appendNode('leader', null, leader.text() )
}
}
错误:代码未根据匹配找到的经理 ID 过滤领导 ID
> java.lang.NoSuchMethodException: No signature of method:
> groovy.util.NodeList.appendNode() is applicable for argument types:
> (java.lang.String, null, java.lang.String) values: [leader, null, 000000710000008000000184000005020000053000000638000008750000090600001630000125800001341000014010000152800001623000019900000199300002413000030580000340200004157000051720000525300013698000159520001555000162800016170001647000206000021458000215180002278000249080002629400030650004117000417]
我在您的代码中发现了一些错误:
NodeList
没有 appendNode
这就是发生错误的原因
p
已经是 PerPerson
节点之一,可能会导致代码混乱
ZHR_GET_AWARD_LEADERS.Response
标签在提供的 xml 中不存在,所以我改为 ZZH_LEADER_WF_GET_APPROVERS.Response
我做的是:
- 实例化 'Node' 使用
new Node(p, 'leader', leader.text())
从而在 xml 中创建一个新节点
- 删除了对
children()
的调用并在收集到 leaderMap
之前添加了 collect { it }
- 删除了闭环内的
PerPerson
个调用
- 创建了查找员工领导的算法
groovyide.com/cpi代码
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String
def xml = new XmlParser().parseText(body)
def ns = new groovy.xml.Namespace('http://sap.com/xi/XI/SplitAndMerge')
def rfcNs = new groovy.xml.Namespace('urn:sap-com:document:sap:rfc:functions')
// I HAD TO CHANGE THE LINE BELOW BECAUSE THE XML DIDN't HAVE "ZHR_GET_AWARD_LEADERS.Response"
//for fast search let map PERNR value to a node that contains it, like internal table
def leaderMap = xml[ns.Message2][0][rfcNs.get("ZZH_LEADER_WF_GET_APPROVERS.Response")][0]\
.collect { it }.collectEntries { [it.text().replaceFirst("^0+(?!$)", ""), it] }
// All employee manager's, including the managers themselves
def upManagers = xml[ns.Message1][0].PerPerson[0].collect { it }.collectEntries { p ->
[p.empId.text(), p.userAccountNav.UserAccount.user.User.manager.User.mgrEmpId.text()]
}
// itearte msg1 -> find entry in leaderMap -> add node
xml[ns.Message1][0].PerPerson[0].each { p ->
def manager = p.userAccountNav.UserAccount.user.User.manager.User.mgrEmpId.text()
def leader = leaderMap[manager]
while (!leader && manager) {
manager = upManagers[manager]
leader = leaderMap[manager]
}
def node = new Node(p, 'leader', leader.text())
}
message.setBody(XmlUtil.serialize(xml[ns.Message1][0].PerPerson[0]))
return message
}
我有两个 xml 使用 <multimap>
节点组合在一起。第一个数据源发送员工和经理 ID 信息(节点),第二个数据源发送所有领导者 ID 信息(节点中仅列出领导者 ID,领导者可以是经理的经理或直接经理或 2-up/3-up )它们都组合在<multimap>
标签。
我想遍历 <multimap1>
节点的 <PerPerson>
,检查经理 ID,直到在 中找到领导者 ID,一旦找到领导者 ID,就在员工记录(节点)中添加一个节点。
请帮忙!
XML 文件:
<?xml version='1.0' encoding='UTF-8'?>
<multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
<multimap:Message1>
<PerPerson>
<PerPerson>
<empId>12345</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67891</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
<PerPerson>
<empId>67891</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
<PerPerson>
<empId>56789</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
<PerPerson>
<empId>12123</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67678</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
</PerPerson>
</PerPerson>
</multimap:Message1>
<multimap:Message2>
<rfc:ZZH_LEADER_WF_GET_APPROVERS.Response xmlns:rfc="urn:sap-com:document:sap:rfc:functions">
<LEADER>12123</LEADER>
<LEADER>23234</LEADER>
<LEADER>34345</LEADER>
<LEADER>56567</LEADER>
<LEADER>67678</LEADER>
</rfc:ZZH_LEADER_WF_GET_APPROVERS.Response>
</multimap:Message2>
</multimap:Messages>
所需结果:在上面的员工和经理数据中,在标签内进行迭代,直到经理 ID 是 rfc / get approvers 列表中的领导者 ID 之一。一旦找到,在标签内添加带有 ID 的领导者 ID 标签
<?xml version='1.0' encoding='UTF-8'?>
<PerPerson>
<PerPerson>
<empId>12345</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67891</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>12123<leader>
</PerPerson>
<PerPerson>
<empId>67891</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>12123<leader>
</PerPerson>
<PerPerson>
<empId>56789</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>12123</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>12123<leader>
</PerPerson>
<PerPerson>
<empId>12123</empId>
<userAccountNav>
<UserAccount>
<user>
<User>
<manager>
<User>
<mgrEmpId>67678</mgrEmpId>
</User>
</manager>
</User>
</user>
</UserAccount>
</userAccountNav>
<leader>67678<leader>
</PerPerson>
</PerPerson>
我试过的代码
map = message.getProperties();
def body = message.getBody(java.lang.String) as String;
def messageLog = messageLogFactory.getMessageLog(message);
def xml = new XmlParser().parseText(body)
def ns = new groovy.xml.Namespace('http://sap.com/xi/XI/SplitAndMerge')
def rfcNs = new groovy.xml.Namespace('urn:sap-com:document:sap:rfc:functions')
//for fast search let map PERNR value to a node that contains it, like internal table
def leaderMap = xml[ns.Message1][0][rfcNs.get("ZHR_GET_AWARD_LEADERS.Response")][0].children().collectEntries{ [it.LEADER_LIST.item.text().replaceFirst("^0+(?!$)", ""), it] }
//itearte msg1 -> find entry in leaderMap -> add node
xml[ns.Message2][0].PerPerson[0].each{p->
def emp = p.PerPerson[0]
def leader = leaderMap[p.PerPerson.userAccountNav.UserAccount.user.User.manager.User.mgrEmpId.text()]
if(leader)
{
// def counter = counter + 1
p.PerPerson.appendNode('leader', null, leader.text() )
}
}
错误:代码未根据匹配找到的经理 ID 过滤领导 ID
> java.lang.NoSuchMethodException: No signature of method:
> groovy.util.NodeList.appendNode() is applicable for argument types:
> (java.lang.String, null, java.lang.String) values: [leader, null, 000000710000008000000184000005020000053000000638000008750000090600001630000125800001341000014010000152800001623000019900000199300002413000030580000340200004157000051720000525300013698000159520001555000162800016170001647000206000021458000215180002278000249080002629400030650004117000417]
我在您的代码中发现了一些错误:
NodeList
没有appendNode
这就是发生错误的原因p
已经是PerPerson
节点之一,可能会导致代码混乱ZHR_GET_AWARD_LEADERS.Response
标签在提供的 xml 中不存在,所以我改为ZZH_LEADER_WF_GET_APPROVERS.Response
我做的是:
- 实例化 'Node' 使用
new Node(p, 'leader', leader.text())
从而在 xml 中创建一个新节点
- 删除了对
children()
的调用并在收集到leaderMap
之前添加了 - 删除了闭环内的
PerPerson
个调用 - 创建了查找员工领导的算法
collect { it }
groovyide.com/cpi代码
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String
def xml = new XmlParser().parseText(body)
def ns = new groovy.xml.Namespace('http://sap.com/xi/XI/SplitAndMerge')
def rfcNs = new groovy.xml.Namespace('urn:sap-com:document:sap:rfc:functions')
// I HAD TO CHANGE THE LINE BELOW BECAUSE THE XML DIDN't HAVE "ZHR_GET_AWARD_LEADERS.Response"
//for fast search let map PERNR value to a node that contains it, like internal table
def leaderMap = xml[ns.Message2][0][rfcNs.get("ZZH_LEADER_WF_GET_APPROVERS.Response")][0]\
.collect { it }.collectEntries { [it.text().replaceFirst("^0+(?!$)", ""), it] }
// All employee manager's, including the managers themselves
def upManagers = xml[ns.Message1][0].PerPerson[0].collect { it }.collectEntries { p ->
[p.empId.text(), p.userAccountNav.UserAccount.user.User.manager.User.mgrEmpId.text()]
}
// itearte msg1 -> find entry in leaderMap -> add node
xml[ns.Message1][0].PerPerson[0].each { p ->
def manager = p.userAccountNav.UserAccount.user.User.manager.User.mgrEmpId.text()
def leader = leaderMap[manager]
while (!leader && manager) {
manager = upManagers[manager]
leader = leaderMap[manager]
}
def node = new Node(p, 'leader', leader.text())
}
message.setBody(XmlUtil.serialize(xml[ns.Message1][0].PerPerson[0]))
return message
}