

- 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
I tried different things, but currently, I don't have a "working" solution.
In theory, we can have ECMA function with parameter nodeset, that can do this task.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
I am pretty sure I could do this in ECMA. When you have a hammer, everything can look like a nail.
I have this urge to hit something with XPATH at the moment.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
@geoffc, as I read the XPath string function definitions, they all require string arguments and not a node-set. It does not look like you will find something "clever" for this. Either looping or ECMA would seem to be your options. Possibly an XSLT stylesheet might be an option.
Cheers,
D


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Usually when you pass a nodeset to a string function, it casts it as a string. I think in the testing I was trying it would actually, concat all the strings into the nodset and tehn substring. So only the first value is shown since the rest were substringed away.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Thinking outside the box, if this is in a policy, set dummy operational attribute to those values and then reformat them? I have no idea if this would actually work, just something that popped to my mind.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Thank you, Sebastijan!
You right! In this specific case "thinking outside the box" and reformat operation attribute before copy value to Nodeset will work 🙂
Original doc (just for example):
<?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>
<instance class-name="User" src-dn="\TREE\org\user">
<association>xxx</association>
<attr attr-name="Internet EMail Address">
<value type="string">test1@test</value>
<value type="string">test2@test2.com.long-long-string</value>
</attr>
</instance>
</input>
</nds>
Policy:
<do-reformat-op-attr name="Internet EMail Address">
<arg-value type="string">
<token-substring length="17">
<token-local-variable name="current-value"/>
</token-substring>
</arg-value>
</do-reformat-op-attr>
<do-set-local-variable name="lvNS" scope="policy">
<arg-node-set>
<token-op-attr name="Internet EMail Address"/>
</arg-node-set>
</do-set-local-variable>
<do-set-local-variable name="lvClean" scope="policy">
<arg-node-set>
<token-xpath expression="$lvNS/text()"/>
</arg-node-set>
</do-set-local-variable>
Simulation:
NS2Substring :Applying policy: %+C%14CNS2String%-C.
NS2Substring : Applying to instance #1.
NS2Substring : Evaluating selection criteria for rule 'NS'.
NS2Substring : Rule selected.
NS2Substring : Applying rule 'NS'.
NS2Substring : Action: do-reformat-op-attr("Internet EMail Address",token-substring(length="17",token-local-variable("current-value"))).
NS2Substring : arg-string(token-substring(length="17",token-local-variable("current-value")))
NS2Substring : token-substring(length="17",token-local-variable("current-value"))
NS2Substring : token-substring(length="17",token-local-variable("current-value"))
NS2Substring : token-local-variable("current-value")
NS2Substring : Token Value: "test1@test".
NS2Substring : Arg Value: "test1@test".
NS2Substring : Token Value: "test1@test".
NS2Substring : Arg Value: "test1@test".
NS2Substring : arg-string(token-substring(length="17",token-local-variable("current-value")))
NS2Substring : token-substring(length="17",token-local-variable("current-value"))
NS2Substring : token-substring(length="17",token-local-variable("current-value"))
NS2Substring : token-local-variable("current-value")
NS2Substring : Token Value: "test2@test2.com.long-long-string".
NS2Substring : Arg Value: "test2@test2.com.long-long-string".
NS2Substring : Token Value: "test2@test2.com.l".
NS2Substring : Arg Value: "test2@test2.com.l".
NS2Substring : Action: do-set-local-variable("lvNS",scope="policy",arg-node-set(token-op-attr("Internet EMail Address"))).
NS2Substring : arg-node-set(token-op-attr("Internet EMail Address"))
NS2Substring : token-op-attr("Internet EMail Address")
NS2Substring : Token Value: {<value> @type = "string",<value> @type = "string"}.
NS2Substring : Arg Value: {<value> @type = "string",<value> @type = "string"}.
NS2Substring : Action: do-set-local-variable("lvClean",scope="policy",arg-node-set(token-xpath("$lvNS/text()"))).
NS2Substring : arg-node-set(token-xpath("$lvNS/text()"))
NS2Substring : token-xpath("$lvNS/text()")
NS2Substring : Token Value: {"test1@test","test2@test2.com.l"}.
NS2Substring : Arg Value: {"test1@test","test2@test2.com.l"}.
NS2Substring :Policy returned:
NS2Substring :
<nds dtdversion="4.0" ndsversion="8.x">
<source>
<product version="4.8.2.0">DirXML</product>
<contact>NetIQ Corporation</contact>
</source>
<input>
<instance class-name="User" src-dn="\TREE\org\user">
<association>xxx</association>
<attr attr-name="Internet EMail Address">
<value type="string">test1@test</value>
<value type="string">test2@test2.com.l</value>
</attr>
</instance>
</input>
</nds>


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
That is a clever idea. The question is now one of performance. This is at the heart of a reasonably and slower than I want process, so I do not want to slow it down even more.
But this particular task is a rare one, so maybe not too bad...
You actually took my thought, that I wanted to 'reformat op attr' inside a nodeset of values and made it into a stated idea that can work. Good one!

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Depending on your use case, maybe you can use the join verb to convert it to a string, use regexp and then split it into a nodeset again? Something like this:
<do-set-local-variable name="yourSubstringedAttribute" scope="policy">
<arg-node-set>
<token-split delimiter="someUniqueString">
<token-replace-all regex="someUniqueString.{3}" replace-with="someUniqueString">
<token-join delimiter="someUniqueString">
<token-local-variable name="yourAttribute"/>
</token-join>
</token-replace-all>
</token-split>
</arg-node-set>
</do-set-local-variable>
Though it would only be able to substring at the beginning or end of the values, and it would break if any value is shorter than the length your're removing. I haven't tested this so there might be other issues.


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Join is an interesting idea I had not considered. Can you explain your regex in there?
Replace SomeUniquestring.[3] with SomeUniquestring, ah I get it.
Join it with commas, (SomeUnqiueString variable) and then that string (a comma) followed by three characters.
Cute. Not sure that really handles my case well but a good idea! Thanks!

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
If I would give that a try I would do a for-each, iterating the values get each of them and reformat, strip the current value and then use Append XML Text to insert the reformatted value.
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.
Best regards,
Tobias


- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
That is an interesting idea as well, thank you.
I had already tested with for-each loop and copy to a new nodeset. Using a counter to strip the positional and insert is also a good idea.
Trying to think of which way is faster.