Lothar Haeger wrote:

> sivaramtm wrote:
>
> >
> > Hi,
> >
> > We have requirement where we need to compare the roles/groups between
> > IDM and RACF and then sync them back to IDM. I tried to use the xpath
> > expressions from the forums and getting empty values as result. Can you
> > please help us out?

>
> As you can see in the trace, your variables contain nodesets of <value> nodes:
>
> > [11/29/15 13:10:24.798]:BCC-RACF ST: Arg Value: {<value>
> > @association-ref = "GROUP\Z61309",<value> @association-ref =
> > "GROUP\Z51212",<value> @association-ref = "GROUP\Z59761",<value>
> > @association-ref = "GROUP\Z56721",<value> @association-ref =
> > "GROUP\Z60425",<value> @association-ref = "GROUP\Z50250",<value>
> > @association-ref = "GROUP\Z00000"}.

>
>
> > [11/29/15 13:10:24.814]:BCC-RACF ST: Arg Value: {<value>
> > @timestamp = "1448697153#12" @type = "string",<value> @timestamp =
> > "1448697153#27" @type = "string",<value> @timestamp = "1448697153#42"
> > @type = "string",<value> @timestamp = "1448697154#6" @type =
> > "string",<value> @timestamp = "1448697154#21" @type = "string",<value>
> > @timestamp = "1448697154#36" @type = "string",<value> @timestamp =
> > "1448697155#6" @type = "string"}.

>
> So in :
>
> > [11/29/15 13:10:24.814]:BCC-RACF ST: Action:
> > do-set-local-variable("ToAdd",scope="policy",arg-node-set(token-xpath("$lv_use
> > rracfgrps[not(string(.) = $RACFIDMRoles)]"))).

>
> I'd try an xpath like
>
> $lv_userracfgrps/value[not(text() = $RACFIDMRoles/value/text())]



This is not necessary (it is mostly cosmetic in this scenario). The original expression is actually correct and the expressions did work.

There were two problems.

1. In the example trace posted the group membership (value-identity wise) was identical between IDV and App. So an empty result is the correct result for this user, no changes are required.
2. You had add and remove, but used the same xpath expression for both. One must be the inverse of the other.

Try the following:

<do-set-local-variable name="lv_userracfgrps" scope="policy">
<arg-node-set>
<token-src-attr name="DirXML-RACF-groups">
<arg-association>
<token-local-variable name="lvUsrAssociationmod"/>
</arg-association>
</token-src-attr>
</arg-node-set>
</do-set-local-variable>
<do-set-local-variable name="RACFIDMRoles" scope="policy">
<arg-node-set>
<token-dest-attr name="BCCRACFRoles">
<arg-association>
<token-local-variable name="lvUsrAssociationmod"/>
</arg-association>
</token-dest-attr>
</arg-node-set>
</do-set-local-variable>
<do-set-local-variable name="ToAdd" scope="policy">
<arg-node-set>
<token-xpath expression="$RACFIDMRoles[not(string(.) = $lv_userracfgrps)]/text()"/>
</arg-node-set>
</do-set-local-variable>
<do-set-local-variable name="ToRemove" scope="policy">
<arg-node-set>
<token-xpath expression="$lv_userracfgrps[not(string(.) = $RACFIDMRoles)]/text()"/>
</arg-node-set>
</do-set-local-variable>

See how the second expression is inverted.

Note that the /text() at the end of each expression is purely cosmetic so that the actual values are shown in the trace.
So even if you omit the /text(), but evaluate the resultant node-set in the correct context (like in a for-each loop) and evaluate $current-node in a string context. The engine will handle the conversion for you.
I think that is what Lothar was trying to say.

Shameless plug: go and read my article all about these type of operations. https://www.netiq.com/communities/co...et-operations/ lots of useful info there.