

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
How to substring all values in a nodeset?
I have a variable with a nodeset of values (imagine Set local variable to Source Attribute, that is multivalued.) and need to substring all the values...
Trying to think of the best way to do this... I thought perhaps set local variable NODE to Xpath of substring($NODE,0,$LENGTH) but that returns nothing.
Of course I could for-each over it and copy it into a new nodeset. But I want something more clever.
Hmm, could I clone by XPATH into a new one, with a substring in the clone? Well first try did not work.
I feel like I am missing something obvious...


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
@tljunggren wrote:You will probably need a counter that keeps track of the current value node and use that in Strip By XPath Expression and Append XML Text.
No counter needed, just use $current-node:
<do-for-each>
<arg-node-set>
<token-local-variable name="nodeset"/>
</arg-node-set>
<arg-actions>
<do-set-local-variable name="substring" scope="policy">
<arg-string>
<token-xpath expression="substring-before($current-node,'@')"/>
</arg-string>
</do-set-local-variable>
<do-strip-xpath expression="$current-node/text()"/>
<do-append-xml-text expression="$current-node">
<arg-string>
<token-text xml:space="preserve">$substring$</token-text>
</arg-string>
</do-append-xml-text>
</arg-actions>
</do-for-each>
Test : Applying rule 'Reformat Nodeset'.
Test : Action: do-set-local-variable("nodeset",scope="policy",arg-node-set(token-src-attr("Internet EMail Address"))).
Test : arg-node-set(token-src-attr("Internet EMail Address"))
Test : token-src-attr("Internet EMail Address")
Test : Query from policy
Test :
<nds dtdversion="4.0" ndsversion="8.x">
<source>
<product version="4.8.2.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<input>
<query class-name="User" dest-dn="o=dirXML Test\ou=Users\cn=User1" scope="entry">
<read-attr attr-name="Internet EMail Address"/>
</query>
</input>
</nds>
Test : Query from policy result
Test :
<nds dtdversion="4.0" ndsversion="8.x">
<source>
<product version="4.8.2.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<output>
<instance class-name="User">
<attr attr-name="Internet EMail Address">
<value type="string">geoffc@cisny.com</value>
<value type="string">geoffrey@gmail.org</value>
</attr>
</instance>
</output>
</nds>
Test : Token Value: {<value> @type = "string",<value> @type = "string"}.
Test : Arg Value: {<value> @type = "string",<value> @type = "string"}.
Test : Action: do-set-local-variable("trace",scope="policy",token-xml-serialize(notrace="true",token-local-variable("nodeset",notrace="true"))).
Test : arg-string(token-xml-serialize(notrace="true",token-local-variable("nodeset",notrace="true")))
Test : token-xml-serialize(notrace="true",token-local-variable("nodeset",notrace="true"))
Test : -- trace suppressed --
Test : Arg Value: "<value type="string">geoffc@cisny.com</value><value type="string">geoffrey@gmail.org</value>".
Test : Action: do-for-each(arg-node-set(token-local-variable("nodeset"))).
Test : arg-node-set(token-local-variable("nodeset"))
Test : token-local-variable("nodeset")
Test : Token Value: {<value> @type = "string",<value> @type = "string"}.
Test : Arg Value: {<value> @type = "string",<value> @type = "string"}.
Test : Performing actions for local-variable(current-node) = <value> @type = "string".
Test : Action: do-set-local-variable("substring",scope="policy",token-xpath("substring-before($current-node,'@')")).
Test : arg-string(token-xpath("substring-before($current-node,'@')"))
Test : token-xpath("substring-before($current-node,'@')")
Test : Token Value: "geoffc".
Test : Arg Value: "geoffc".
Test : Action: do-strip-xpath("$current-node/text()").
Test : Action: do-append-xml-text("$current-node","$substring$").
Test : arg-string("$substring$")
Test : token-text("$substring$")
Test : Expanded variable reference '$substring$' to 'geoffc'.
Test : Arg Value: "geoffc".
Test : Performing actions for local-variable(current-node) = <value> @type = "string".
Test : Action: do-set-local-variable("substring",scope="policy",token-xpath("substring-before($current-node,'@')")).
Test : arg-string(token-xpath("substring-before($current-node,'@')"))
Test : token-xpath("substring-before($current-node,'@')")
Test : Token Value: "geoffrey".
Test : Arg Value: "geoffrey".
Test : Action: do-strip-xpath("$current-node/text()").
Test : Action: do-append-xml-text("$current-node","$substring$").
Test : arg-string("$substring$")
Test : token-text("$substring$")
Test : Expanded variable reference '$substring$' to 'geoffrey'.
Test : Arg Value: "geoffrey".
Test : Action: do-set-local-variable("trace",scope="policy",token-xml-serialize(notrace="true",token-local-variable("nodeset",notrace="true"))).
Test : arg-string(token-xml-serialize(notrace="true",token-local-variable("nodeset",notrace="true")))
Test : token-xml-serialize(notrace="true",token-local-variable("nodeset",notrace="true"))
Test : -- trace suppressed --
Test : Arg Value: "<value type="string">geoffc</value><value type="string">geoffrey</value>".
https://www.is4it.de/identity-access-management


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
That is more like what I was looking for. Still not quite the clever XPATH to do it all in one action, but I guess this one won't do it.
Thanks, that helps.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
I actually use the above scheme a lot instead of token do-reformat-op-attr to preserve xml attrs on the value nodes that would otherwise be lost (here: value/@timestamp )
<?xml version="1.0" encoding="UTF-8"?><nds dtdversion="4.0" ndsversion="8.x">
<source>
<product version="4.8.2.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<input>
<modify class-name="User" qualified-src-dn="o=dirXML Test\ou=Users\cn=User1" src-dn="o=dirXML Test\ou=Users\cn=User1">
<association>o=dirXML Test\ou=Users\cn=User1</association>
<modify-attr attr-name="Internet EMail Address">
<remove-value>
<value timestamp="20200101-9991231" type="string">geoffrey@gmail.org</value>
</remove-value>
<add-value>
<value timestamp="20200101-9991231" type="string">geoffc@cisny.com</value>
</add-value>
</modify-attr>
</modify>
</input>
</nds>
Test :Applying policy: %+C%14Ctest%-C.
Test : Applying to modify #1.
Test : Evaluating selection criteria for rule 'Reformat Nodeset'.
Test : Rule selected.
Test : Applying rule 'Reformat Nodeset'.
Test : Action: do-reformat-op-attr("Internet EMail Address",token-xpath("substring-before($current-value,'@')")).
Test : arg-string(token-xpath("substring-before($current-value,'@')"))
Test : token-xpath("substring-before($current-value,'@')")
Test : Token Value: "geoffrey".
Test : Arg Value: "geoffrey".
Test : arg-string(token-xpath("substring-before($current-value,'@')"))
Test : token-xpath("substring-before($current-value,'@')")
Test : Token Value: "geoffc".
Test : Arg Value: "geoffc".
Test :Policy returned:
Test :
<nds dtdversion="4.0" ndsversion="8.x">
<source>
<product version="4.8.2.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<input>
<modify class-name="User" qualified-src-dn="o=dirXML Test\ou=Users\cn=User1" src-dn="o=dirXML Test\ou=Users\cn=User1">
<association>o=dirXML Test\ou=Users\cn=User1</association>
<modify-attr attr-name="Internet EMail Address">
<remove-value>
<value type="string">geoffrey</value>
</remove-value>
<add-value>
<value type="string">geoffc</value>
</add-value>
</modify-attr>
</modify>
</input>
</nds>
Test :Applying policy: %+C%14Ctest%-C.
Test : Applying to modify #1.
Test : Evaluating selection criteria for rule 'Reformat Nodeset'.
Test : Rule selected.
Test : Applying rule 'Reformat Nodeset'.
Test : Action: do-for-each(arg-node-set(token-removed-attr("Internet EMail Address")+token-op-attr("Internet EMail Address"))).
Test : arg-node-set(token-removed-attr("Internet EMail Address")+token-op-attr("Internet EMail Address"))
Test : token-removed-attr("Internet EMail Address")
Test : Token Value: {<value> @timestamp = "20200101-9991231" @type = "string"}.
Test : token-op-attr("Internet EMail Address")
Test : Token Value: {<value> @timestamp = "20200101-9991231" @type = "string"}.
Test : Arg Value: {<value> @timestamp = "20200101-9991231" @type = "string",<value> @timestamp = "20200101-9991231" @type = "string"}.
Test : Performing actions for local-variable(current-node) = <value> @timestamp = "20200101-9991231" @type = "string".
Test : Action: do-set-local-variable("substring",scope="policy",token-xpath("substring-before($current-node,'@')")).
Test : arg-string(token-xpath("substring-before($current-node,'@')"))
Test : token-xpath("substring-before($current-node,'@')")
Test : Token Value: "geoffrey".
Test : Arg Value: "geoffrey".
Test : Action: do-strip-xpath("$current-node/text()").
Test : Action: do-append-xml-text("$current-node","$substring$").
Test : arg-string("$substring$")
Test : token-text("$substring$")
Test : Expanded variable reference '$substring$' to 'geoffrey'.
Test : Arg Value: "geoffrey".
Test : Performing actions for local-variable(current-node) = <value> @timestamp = "20200101-9991231" @type = "string".
Test : Action: do-set-local-variable("substring",scope="policy",token-xpath("substring-before($current-node,'@')")).
Test : arg-string(token-xpath("substring-before($current-node,'@')"))
Test : token-xpath("substring-before($current-node,'@')")
Test : Token Value: "geoffc".
Test : Arg Value: "geoffc".
Test : Action: do-strip-xpath("$current-node/text()").
Test : Action: do-append-xml-text("$current-node","$substring$").
Test : arg-string("$substring$")
Test : token-text("$substring$")
Test : Expanded variable reference '$substring$' to 'geoffc'.
Test : Arg Value: "geoffc".
Test :Policy returned:
Test :
<nds dtdversion="4.0" ndsversion="8.x">
<source>
<product version="4.8.2.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<input>
<modify class-name="User" qualified-src-dn="o=dirXML Test\ou=Users\cn=User1" src-dn="o=dirXML Test\ou=Users\cn=User1">
<association>o=dirXML Test\ou=Users\cn=User1</association>
<modify-attr attr-name="Internet EMail Address">
<remove-value>
<value timestamp="20200101-9991231" type="string">geoffrey</value>
</remove-value>
<add-value>
<value timestamp="20200101-9991231" type="string">geoffc</value>
</add-value>
</modify-attr>
</modify>
</input>
</nds>
The fact that you can apply this to every kind of nodeset makes it very flexible and powerful. You can e.g. easily reformat several operation attributes at a time or only reformat the removed values or values matching a certain regex (or whatever selection you can make in xpath).
https://www.is4it.de/identity-access-management

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Depending on the situation you should store the values already (re)formatted in the IDVault. If you really have to do the operation you describe I'd use XSLT since it concerns a node-set. The example stylesheet below consists of the default identity transformation template and a template for matching and reformatting the attribute 'mail' on a modify event. You'd have to adjust the stylesheet to match the event and attribute you want to reformat.
Example stylesheet:
<!-- identity transformation template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- reformat multivalued attrs -->
<xsl:template match="modify/modify-attr[@attr-name='mail']/add-value/value/text()">
<xsl:value-of select="substring(.,0,7)"/>
</xsl:template>
</xsl:stylesheet>
Sample Input XDS with modify event:
<modify class-name="User" qualified-src-dn="o=dirXML Test\ou=Users\cn=User1">
<association>o=dirXML Test\ou=Users\cn=User1</association>
<modify-attr attr-name="mail">
<remove-all-values/>
<add-value>
<value type="string">Last1@Name1</value>
<value type="string">Last2@Name1</value>
<value type="string">Last3@Name1</value>
</add-value>
</modify-attr>
</modify>
</input>
Sample Output XDS after stylesheet processing:
<modify class-name="User" qualified-src-dn="o=dirXML Test\ou=Users\cn=User1">
<association>o=dirXML Test\ou=Users\cn=User1</association>
<modify-attr attr-name="mail">
<remove-all-values/>
<add-value>
<value type="string">Last1@</value>
<value type="string">Last2@</value>
<value type="string">Last3@</value>
</add-value>
</modify-attr>
</modify>


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
I knew I could do it in a stylesheet. I need this in the middle of a policy buried deep in a loop.
I made it work nicely, using simply the Split token. I wanted initially to keep the <value> nodes, and split the one <value> node to many <value> nodes, but realized I could live with a simple nodeset of values so easy enough to do by changing the requirements.
- « Previous
-
- 1
- 2
- Next »