We were recently asked to provide code which satisfied the following specification:
- In flowdata for a PRD I am trying to do the following in a mapping activity.
- I have a string, shown below
2012-06-20T12:26:32.000+02:00 2012-07-17T12:26:32.000+02:00 24222 24300 cn=ADMKEVRAS,ou=sa,o=data Test 11 [DN on a group] - This string is just a stringified XML stored in a Case Ignore String attribute in edirectory. In clean XML it looks like this:
<data>
<startdate>2012-06-20T12:26:32.000+02:00</startdate>
<enddate>2012-07-17T12:26:32.000+02:00</enddate>
<udlaaner>24222</udlaaner>
<modtager>24300</modtager>
<initiator>cn=ADMKEVRAS,ou=sa,o=data</initiator>
<desc>
<value>Test 11</value>
</desc>
<A1>[DN on a group]</A1>
</data>
-
I need to convert this string to an XML document in order to add one more child node to the
node and also to change the value of the node. After this I need to stringify the XML document again in order to save the updated information to the String attribute in edirectory.
The Solution
In order to do what the request asks, the following steps are required:
- If using a version of Novell IDM prior to 4, you’ll need to add this ECMAScript as a function to whichever mapping activity requires it. If using Novell IDM version 4 and above, you can add this script as a global script and attach it to the Workflow directly; the code can then be called from all mapping activities within that Workflow
- Read the string out of the directory
- Ensure the string can be converted to an XML document (replace the < and > tags)
- Convert the string into an XML document
- Add the new node and replace the text in the
... node - Convert the XML document back into a String, and store it in the directory
The JavaScript / ECMAScript code for the solution is shown below
function String2XML(varString)
{
// Let's set a few variables so we can test the code a bit better
var varNameOfNewDescNode = 'new-desc-node';
var varValueOfNewDescNode = 'This is a value';
var varNewValueForStartDate = 'BELKAST CONSULTING'
var varNewValueforEndDate = 'Keith Armstrong'
// ####################
// Let's just be sure, and get values of '<' and '>' in the replacement value
var varRegexGT = new RegExp(">", "g");
var varRegexLT = new RegExp("<", "g");
varString = varString.replace(varRegexGT, ">");
varString = varString.replace(varRegexLT, "<");
var dbf = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
var builder = dbf.newDocumentBuilder();
var stringreader = Packages.java.io.StringReader;
var strinput = new stringreader(varString);
var inputsource = new Packages.org.xml.sax.InputSource(strinput);
var doc = builder.parse(inputsource);
// Now let's read the desc element...we need to add something on there
var nodeList = doc.getElementsByTagName('desc');
var node = nodeList.item(0);
var newDescNode = doc.createElement(varNameOfNewDescNode);
newDescNode.appendChild(doc.createTextNode(varValueOfNewDescNode));
node.appendChild(newDescNode);
// Now let's get the start date element, and put our own value in there
var nodeList = doc.getElementsByTagName('startdate');
var node = nodeList.item(0);
node.textContent = varNewValueForStartDate;
// Now let's get the end date element, and put our own value in there
var nodeList = doc.getElementsByTagName('enddate');
var node = nodeList.item(0);
node.textContent = varNewValueforEndDate;
// Now we need to convert the XML back to a string to store in the attribute
domSource = new Packages.javax.xml.transform.dom.DOMSource(doc);
writer = new Packages.java.io.StringWriter();
result = new Packages.javax.xml.transform.stream.StreamResult(writer);
tf = Packages.javax.xml.transform.TransformerFactory.newInstance();
transformer = tf.newTransformer();
transformer.transform(domSource, result);
writer.flush();
return writer.toString();
}
The string started off looking like this:
The string, once manipulated, looked like this: