Novell Home

Converting to Multi-Value Attributes

Novell Cool Solutions: Tip

Digg This - Slashdot This

Posted: 21 Jul 2005
 

Problem

"I have some fields from a database now coming over(via jdbc) that are multivalued - - separated by commas. I cannot find anything in Policy Builder that would help me convert this to multi-value attributes. I am trying to avoid XSL for maintability reasons (PB is so much easier for someone to follow). Still, I am guessing I will be needing XSL to solve this?"

... And here's some inspiration on the subject from Father Ramon ...

Solution

It can't be done in Policy Builder for arbitrary numbers of CSV values, without the help of some sort of external split function. Fortunately, such a functions exists in DirXML and is documented in the NDK. The first example below is an input transformation that implements the function.

Note that even with the split function it gets kind of ugly because you have to revert to the raw XML actions to turn one value into many in any sort of generic fashion. I also included a stylesheet (see the second example below) that does the same thing without the aid of an external function. In this case the stylesheet is probably simpler and easier to understand.

Example: Input Transformation

<?xml version="1.0" encoding="UTF-8"?><policy xmlns:dt="http://www.novell.com/nxsl/java/com.novell.nds.dirxml.driver.DelimitedText" xmlns:sr="http://www.novell.com/nxsl/java/java.io.StringReader">
<rule>
<description>Split into NodeSet and remove existing node</description>
<conditions>
<or/>
</conditions>
<actions>
<do-for-each>
<arg-node-set>
<token-op-attr name="Given Name"/>
<token-removed-attr name="Given Name"/>
</arg-node-set>
<arg-actions>
<do-set-local-variable name="split">
<arg-node-set>
<token-xpath expression="dt:convertToXML(dt:new(),sr:new(string($current-node)))//field"/>
</arg-node-set>
</do-set-local-variable>
<do-set-local-variable name="parent">
<arg-node-set>
<token-xpath expression="$current-node/.."/>
</arg-node-set>
</do-set-local-variable>
<do-for-each>
<arg-node-set>
<token-local-variable name="split"/>
</arg-node-set>
<arg-actions>
<do-append-xml-element expression="$parent" name="value"/>
<do-append-xml-text expression="$parent/value[last()]">
<arg-string>
<token-local-variable name="current-node"/>
</arg-string>
</do-append-xml-text>
</arg-actions>
</do-for-each>
<do-strip-xpath expression="$current-node"/>
</arg-actions>
</do-for-each>
</actions>
</rule>
</policy>

Example: Stylesheet

<?xml version='1.0'?>
<xsl:stylesheet
version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       
<!-- This is for testing the stylesheet outside of DirXML so things are pretty to look at -->
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="association add-association remove-association value component password check-password"/>
<xsl:output indent="yes" method="xml"/>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="*[@attr-name='Given Name']//value">
<xsl:call-template name="value-splitter">
<xsl:with-param name="input" select="string(.)"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="value-splitter">
<xsl:param name="input" />
<xsl:choose>
<xsl:when test="$input = ''"/>
<xsl:when test="contains($input, ',')">
<value>
<xsl:value-of select="substring-before($input, ',')" />
</value>
<xsl:call-template name="value-splitter">
<xsl:with-param name="input" select="substring-after($input, ',')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<value>
<xsl:value-of select="$input" />
</value>
</xsl:otherwise>
</xsl:choose>
</xsl:template>


</xsl:stylesheet>


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell