Novell Home

How to Define a Corporate Naming Policy Using DirXML Stylesheets

Articles and Tips: article

Karl Bunnell
Senior Software Engineer
Novell Developer Solutions

01 Dec 2001

This AppNote describes how to use DirXML stylesheets to define and enforce adherence to a corporate naming policy when creating user accounts. The automation of the account-creation process provides significant cost savings by relieving IS&T staff from the chore of manually creating and maintaining corporate accounts. It also eliminates human error and enables employees to become productive quickly through the immediate creation of corporate application accounts.

It is recommended that you also read the AppNote entitled "How to Write a Simple DirXML Stylesheet" in the March 2001 issue, available online at


DirXML, Novell eDirectory, XML, XSLT


Novell eDirectory, DirXML


network administrators, programmers



Prerequisite Skills

Java, XML, and XSLT proficiency

Operating System

NetWare 5.x, Windows NT or 2000



Sample Code



This AppNote describes how to compose a DirXML create rule using XSLT (Extensible Stylesheet Language Transformations) and XPath to define and enforce a corporate naming policy. The corporate naming policy is a series of business rules that define how user account names are constructed from data supplied by one or more master data sources. An example of a master data source is a Human Resources (HR) application such as PeopleSoft, Baan, or SAP. These applications are used to collect and maintain key information about an employee such as their name information (given name, middle name, surname, and so on), location, address information, benefit and compensation information, and so on.

The corporate naming policy is used to transform this raw data into account names used to identify a user to corporate applications such as Novell eDirectory, GroupWise, Lotus Notes, and so on. For example, suppose a new employee named John David Doe is hired and entered into the corporate human resources application. The creation of a new record in the HR application generates an event that is submitted to the DirXML driver's publisher channel in the form of an XML document.

As the data flows from the HR application to Novell eDirectory by way of DirXML, the publisher create rule can be used to implement a series of data checks and transformations that generate an account name that conforms to the corporate naming policy. Read on to learn how to compose a DirXML create rule that defines and enforces a corporate naming policy.

Corporate Naming Policy

Every company has a corporate naming policy that governs how account names for corporate applications are defined. The corporate processes that define and enforce the corporate naming policy are often manual and require well-established communication between groups.

For example, the new-hire process is carried out by the HR department. HR then sends a message to the IS&T department to create network accounts, e-mail accounts, and so on. The IS&T staff uses some policy to create the names for these accounts that ensures each account name is unique and follows a corporate naming standard. Often the policy is very loose and new employees may be asked what e-mail or network ID they would like to use. In other cases, a policy is well-defined that stipulates explicitly how an account name is to be constructed.

An example of a primary naming policy is an account name that consists of first letter of the given name concatenated with the surname. In the case of John David Doe, the corporate naming policy would yield the account name JDoe. The naming policy must also detect name collisions and provide additional fallback policies to ensure that corporate account names are unique.

As the number of employees grows in a company, it becomes more difficult to avoid name collisions and the automation of the account creation process that enforces compliance with a corporate naming policy becomes a necessity. This is where DirXML and create rules come to the rescue.

DirXML Create Rcreate ruleule

DirXML provides a policy engine that allows business rules to be defined and enforced on data as it moves from disparate, external systems to eDirectory, and as it flows from eDirectory to the connected external systems. An HR application typically triggers the first event in the life of an employee record, as this marks the "new hire" status of a new employee. This employee record information is considered "raw," as it has yet to be transformed to meet the demands of the corporate applications that need to consume it.

The raw employee data is submitted via the publisher channel of the DirXML driver that provides connectivity between the HR application and the DirXML engine. As this data moves through the publisher channel, it is acted on by a number of rules and data transformation stylesheets, one of which is the publisher create rule. At a minimum, the create rule defines the set of data required to create an object in the target system. This AppNote focuses on how the create rule can act on the data to define and enforce the corporate naming policy.

For purposes of this AppNote, the focus is on the publisher channel; thus eDirectory is the target system. For example, in order to create a User object in eDirectory, the minimum data set required is mandated by the mandatory attributes of the object class "User", which include an object class, a common name (CN), and a surname. The create rule, if it is doing its job, must ensure that these attributes exist in the <add> document. Otherwise, the create rule will "veto" the operation and the DirXML engine will return an error to the originating driver indicating that the add operation could not be completed.

A simple create rule can be defined using a series of XML tags that stipulate the object class and attributes that must exist in order for the add operation to continue successfully. The XML tags shown below demonstrate a simple create rule that stipulates that the object class must be of type "User" and values for the "Given Name" and "Surname" attributes must exist in the <add> document in order for the object creation to be allowed to complete.

    <create-rule class-name="User">
        <required-attr attr-name="Given Name"/>
        <required-attr attr-name="Surname"/>

While this create rule provides a simple way to define creation criteria, an XSLT stylesheet is required to define more complex object creation requirements such as a corporate naming policy.

To create a create rule stylesheet, follow the steps below.

  1. In ConsoleOne, create a DirXML-StyleSheet object beneath the Publisher object.

  2. Right-click the Publisher object, select Properties, and then select the Other tab.

  3. Add a new attribute named "DirXML-CreateRule" and add the DirXML- StyleSheet object as the value (see Figure 1).

Adding a DirXML-Stylesheet object to the Publisher object.

DirXML will now rely on the DirXML-StyleSheet object contents to carry out the function of a create rule.

Note: To see a functioning example of how to implement all of the techniques discussed in this AppNote, download the sample DirXML driver from Extract the file and read the included README.TXT for instructions on how to install and configure this driver to work in an existing DirXML deployment.

Once the DirXML-StyleSheet object is in place as the DirXML-CreateRule, you are ready to start the work of authoring XSLT and XPath to fulfill the function of the create rule and to define a corporate naming policy.

Composing the Create Rule

The first order of business when authoring a create rule using XSLT is to ensure that the create rule stylesheet serves its primary function. In this case, that is to ensure that the required attributes are present in the <add> document. This is accomplished by defining an XSLT template that filters all elements but the <add> element (see line 02 in the listing below).

01    <xsl:transform version="1.0" xmlns:hrxyz="
    dirxml/drivers/HRxyz" xmlns:query="
02        <xsl:template match="add">
03            <!-- ensure we have required NDS attributes -->
04            <xsl:if test="add-attr[@attr-name='Surname'] and
            add-attr[@attr-name='Given Name'] and
            hrxyz:policy-attr[@hrxyz:attr-name='Middle Name']">
05                <!-- copy the add through -->
06                <xsl:copy>
07                    <xsl:apply-templates select="@*"/>
08                    <!-- Call template to create name according to policy.-->
09                    <xsl:variable name="object-name">
10                        <xsl:call-template name="create-object-name"/>
11                    </xsl:variable>
12                    <add-attr attr-name="CN">
13                        <value type="string">
14                            <xsl:value-of select="$object-name"/>
15                        </value>
16                    </add-attr>
17                    <!-Copy everything else through. -->
18                    <xsl:apply-templates select="* | comment() |
                     processing-instruction() | text()"/>
19                </xsl:copy>
20            </xsl:if>
21        </xsl:template>
. . .

Within the "add" template, an XSLT <xsl:if> instruction is used to ensure that required attributes are present in the <add> document. Otherwise, the content of the <add> document is not copied to the result document to be submitted to the DirXML engine for processing. If the content of the <add> document is not copied, the operation is "vetoed" by the create rule. Processing of the event is terminated and an error indicating such is returned to the DirXML driver.

The <xsl:if> instruction is defined as follows (line 04):

<xsl:if test="add-attr[@attr-name='Surname'] and add-attr[@attr-name='Given
Name'] and hrxyz:policy-attr[@hrxyz:attr-name='Middle Name']">

The "test" expression is evaluated by determining if each of the selected attributes (Surname, Given Name, and Middle Name) exists in the source <add> document.

One of the expressions merits further explanation. The hrxyz:policy-attr[@ hrxyz:attr-name='Middle Name' expression looks for an attribute defined in the "hrxyz" namespace. The DirXML engine ignores attributes defined in other XSL namespaces, which presents some interesting implications. The use of an application-defined XSL namespace provides a mechanism to pass application data to a stylesheet that does not need to be mapped via an eDirectory attribute. Therefore, the create rule stylesheet can use this "policy" data to construct an account name without the requirement that the data be mapped to an eDirectory attribute.

In order to use a namespace, it must be defined as an attribute on a parent element relative to where it is used. The namespace attribute is defined as follows:


In this example, this attribute is added to the <xsl:transform> element at the top of the create rule stylesheet (line 01), which allows the "hrxyz" namespace to be used within any element in the stylesheet.

Nested within the <xsl:if> tags (lines 04 and 20) are the <xsl:copy> tags (lines 06 and 19). The <xsl:copy> instruction copies data from the source <add> document as instructed by the <xsl:apply-templates> instructions on line 07 (copy all attributes) and line 18 (copy other elements, text and instructions) to the result document to be submitted to the DirXML engine for processing.

The real work of defining the naming policy begins on line 09. An <xsl:variable> named "object-name" is defined by calling a template (line 10) named "create- object-name". The object-name variable will contain the account name as generated by the call to the <xsl:call-template name="create-object-name"/> instruction. The <add-attr attr-name="CN"> instruction (lines 12 - 16) adds an attribute named "CN" (common name) to the resultant <add> document.

Notice on line 14 that the value of the object-name variable is selected as the value for the new CN attribute. The CN attribute is referenced by the publisher placement rule to create the object in the proper location within eDirectory with the proper name. The publisher placement rule is listed below:

<?xml version="1.0" encoding="UTF-8"?>
<placement-rules dest-dn-format="slash" src-dn-format="slash">
        <match-class class-name="User"/>

To summarize what occurs in the <xsl:template match="add"> template: First, it ensures that processing continues only if the required attributes are included in the source <add> document. Second, if the required attributes are present, it copies the relevant data from the source <add> document to the resultant <add> document. Third, it calls the "create-object-name" template to generate the account name according to corporate naming policy. Finally, it adds an attribute named "CN" to the resultant <add> document so an object with a name that complies with the corporate naming policy can be created within eDirectory as directed by the placement rule.

It is important to note that the other external applications connected via DirXML will receive a corresponding <add> event with the account name generated by the naming policy. These applications can then leverage the use of this account name to create e-mail accounts, database accounts, PBX accounts, and so on, thus ensuring that all corporate applications comply with the corporate naming standard.

Now that the work of creating the resultant <add> document is understood, the key details of how to define and enforce the corporate naming policy can be analyzed. The magic occurs in the call to the "create-object-name" template, which was called from the "add" template.

Defining a Corporate Naming Policy Using XSLT

The real work of defining the corporate naming policy begins in the "create- object-name" template. This template represents the primary naming policy, which is defined as the first letter of the first name concatenated with the last name. The template is listed below:

01    <xsl:template name="create-object-name">
02        <!-- first try is first letter first name followed by surname
03        <xsl:variable name="given-name" select="add-attr[@attr-name='Given
04        <xsl:variable name="surname" select="add-attr[@attr-name='Surname']
05        <xsl:variable name="prefix" select="substring($given-name,0,2)"/>
06        <xsl:variable name="object-name" select="concat($prefix,$surname)"/>
07        <!-- then see if name already exists in NDS -->
08        <xsl:variable name="exists">
09            <xsl:call-template name="query-object-name">
10                <xsl:with-param name="object-name" select="$object-name"/>
11            </xsl:call-template>
12        </xsl:variable>
13        <!-- if exists, then try 1st fallback, else return result
14        <xsl:choose>
15            <xsl:when test="string-length($exists) != 0">
16                <xsl:call-template name="create-object-name-2"/>
17            </xsl:when>
18            <xsl:otherwise>
19                <xsl:value-of select="$object-name"/>
20            </xsl:otherwise>
21        </xsl:choose>
22    </xsl:template>

Lines 03 through 06 do the work of defining variables that contain the values of the name components used to create the proposed account name. Notice that XPath string functions (substring() and concat( )) are used to retrieve the name components from the source <add> document and to concatenate the components together to create the account name candidate contained in the "object-name" variable (line 05).

Next, lines 08 through 11 define a variable named "exists" that is populated by a call to a template named "query-object-name". The query-object-name template is passed a parameter "object-name" which contains the proposed account name as constructed on lines 03 - 06. The query-object-name template is used to submit a query to eDirectory to determine if the proposed account name is already in use by an existing object (more about this in the next section). If it is, the template will return the name of the object, otherwise, nothing will be returned. The variable "exists" will contain the result of the query.

The logic on lines 14 through 21 determines whether a name collision occurred. If the length of the "exists" variable is zero, then the proposed account name does not exist in eDirectory and is therefore a valid, unique account name that complies with the corporate naming policy. This signals that the search for a unique name that complies with the corporate naming policy is complete. The account name is returned to the calling template and is added as the value of the "CN" attribute of the resultant <add> document.

If the "exists" variable contains a value, the proposed account caused a name collision. A second template named "create-object-name-2" is called to continue the search for a unique name that complies with a fallback naming policy. The create-object-name-2 template utilizes the same logic as the create-object-name template but simply generates a new account name candidate based on a secondary naming policy.

In the case of this example, the first fallback policy consists of the first letter of the first name, the first letter of the middle name, and the last name concatenated together in that order. This "chaining" of calls to additional create-object templates continues until the proposed account name does not cause a naming collision with an existing object in eDirectory.

It is customary to have a final fallback policy that will yield a unique name when all the previous proposed names have caused a collision. This can be accomplished by generating a name that includes a sequential numerical digit (for example, Jdoe1, Jdoe2, and so on) or by including a value that is known to be unique, such as the user's employee ID as part of the account name (for example, Jdoe02124). The example included with this article uses a sequential digit concatenated to the name to ensure uniqueness of name as the final fallback policy.

To summarize, the initial call to the create-object-name template begins the execution of the corporate naming policy. Each create-object-name template generates a new account name candidate and submits it for approval by querying eDirectory to determine if the proposed name already exists in eDirectory. Each successive call to an additional create-object-name template represents a fallback policy used to resolve name collisions. In the end, the account name returned to the "add" template represents a unique account name that complies with the corporate naming policy.

Submitting a Query to eDirectory from a Stylesheet

Novell eDirectory is the central hub of the DirXML-connected framework and therefore serves as the master repository for account names. In order to ensure that a proposed name is unique, the create rule must have the capability to query the master repository, eDirectory, to determine if a proposed account name is unique.

Fortunately, DirXML provides a powerful mechanism to query eDirectory by submitting a query document that complies with the DirXML DTD. The DirXML engine passes two useful parameters named srcQueryProcessor and destQuery- Processor to every stylesheet that it processes. These are references to the source and destination query processors. In the case of the publisher channel, the destQueryProcessor represents the call interface used to query eDirectory and the srcQueryProcessor represents the call interface used to query the application driver. For the subscriber channel, the call interface of these parameters is swapped; that is, the srcQueryProcessor is used to query eDirectory and destQueryProcessor is used to query the application driver.

References to these objects are made available by adding the following lines beneath the <xsl:transform> element of the stylesheet:

<xsl:param name="srcQueryProcessor"/>
<xsl:param name="destQueryProcessor"/>

One piece of the puzzle is still missing: how to issue the query to eDirectory. A reference to the actual query object is made available to the stylesheet by adding the following attribute to the <xsl:transform> element (see line 01 of the add template listing shown previously):


This namespace attribute makes the DirXML query object available for use by any templates within the stylesheet. The "query-object-name" template uses these query facilities to validate whether a proposed object name is unique. The query-object-name template is listed below:

01    <xsl:template name="query-object-name">
02        <xsl:param name="object-name"/>
03        <!-- build an xds query as a result tree fragment -->
04        <xsl:variable name="query">
05            <nds dtdversion="1.0" ndsversion="8.5">
06                <input>
07                    <query>
08                        <search-class class-name="{ancestor-or-self::add
09                        <!-- NOTE: depends on CN being the naming attribute
10                        <search-attr attr-name="CN">
11                            <value>
12                                <xsl:value-of select="$object-name"/>
13                            </value>
14                        </search-attr>
15                        <!-- put an empty read attribute so only object
                          is returned.-->
16                        <read-attr/>
17                    </query>
18                </input>
19            </nds>
20        </xsl:variable>
21        <!-- query eDirectory -->
22        <xsl:variable name="result" select="query:query($destQueryProcessor,
23        <!-- return an empty or non-empty result tree fragment depending
on result of query -->
24        <xsl:value-of select="$result//instance/@class-name"/>
25    </xsl:template>

The query result-tree fragment (think of this as an XML document) is composed on lines 04 through 20 by defining a "query" variable that contains the query content consumable by the DirXML query processor. Notice on line 12 that the passed "object-name" parameter is used as the value of the CN (common name) attribute to query. The query is submitted to eDirectory (line 22) by using the query method and passing the appropriate query processor and query document as input parameters to the method. The "result" variable contains the result of the query.

Note that the XPath statement <xsl:value-of select="$result//instance/ @class-name"/> is used to select the class name of a returned instance. If no instances are returned, the result will be a zero-length string; otherwise, the class name is returned which indicates that the proposed object name does exist in the directory and is therefore in use.


The corporate naming policy, implemented as a DirXML create rule stylesheet, provides a powerful, automated mechanism to enforce corporate naming standards that are leveraged by all corporate applications interconnected via DirXML. The automation of the account-creation process enables strict enforcement of the corporate naming policy, eliminates human error, enables employees to become productive quickly through the immediate creation of corporate application accounts. It also provides significant cost savings by relieving IS&T staff from the chore of manually creating and maintaining corporate accounts.

* Originally published in Novell AppNotes


The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© 2014 Novell