Support Download Buy Contact Us Log-In Log-Out
Novell Home
       APPNOTES HOME ARTICLES SECTIONS INDEX/ARCHIVE
ProductsEducationConsultingCompany
Advanced SearchSubmit Search

How to Analyze NDS.DTD to Construct XDS Documents for DirXML

Larry Fisher
Senior Software Engineer
DeveloperNet University
lfisher@novell.com

This article discusses how to use NDS.DTD to construct XDS documents describing events for DirXML.

Contents:

Topics
directory services, DirXML, NDS eDirectory
Products
NDS eDirectory, DirXML
Audience
developers, administrators
Level
intermediate
Prerequisite Skills
familiarity with XML
Operating System
NetWare 4.x or 5.x, Windows NT or 2000
Tools
none
Sample Code
yes

Introduction

The DirXML engine communicates with your driver using XDS documents (DirXML's XML vocabulary for directory event information). Everything your driver tells the DirXML engine to do in the directory and everything the directory tells your driver to do will be in the form of an XDS document.

XDS documents must be appropriate both syntactically and semantically in order for the DirXML engine to process them. Just as a blueprint describes the construction of a building, the NDS.DTD document is used to describe the allowable content in XDS documents. The NDS.DTD is like a recipe book for all allowable XDS statements. It is where the grammar for XDS is defined.

This article demonstrates how to use NDS.DTD to construct XDS documents describing events from a sample application called PBXSimulator.

DTDs are a very complicated topic. To stay as simple as possible, this article will only discusses concepts and tasks that are directly relevant to using NDS.DTD to construct appropriate XDS documents.

Elements in the DTD

The DTD (document type definition) used by DirXML to define XDS has three main elements to be concerned with, ENTITY, ELEMENT, and ATTLIST. Here are descriptions for each:

<!ENTITY>
Defines a selection of allowable items.
<!ELEMENT>
Specifies an element that is eligible to be added to an XDS document.
<!ATTLIST>
Specifies the attributes that can be added to an ELEMENT.


<!ENTITY> Elements

The <!ENTITY> element defines a list of possible items. For example, the <!ENTITY Assoc-State> element shown below (taken from NDS.DTD) defines several potential string values that can replace the term "Assoc-State" whenever it is encountered in an XDS document.


<!ENTITY % Assoc-State"not-associated | associated | disabled | migrate | pending
| manual">

The <!ENTITY> element can also describe the location of an external file full of DTD stuff that can be inserted into the DTD document whenever the particular <!ENTITY> symbol occurs, kind of like a C compiler/preprocessor would do with an #include file. However, we won't go into that feature because it is not useful to this discussion.

<!ELEMENT> Elements

In NDS.DTD, the <!ELEMENT nds> element describes an XDS element that can be installed into an XDS document. For example, the <!ELEMENT nds> below is the parent element in all XDS documents in DirXML.


<!ELEMENT nds (source?, (input | output))>

Notice that more than just the name of the element is described. The source?, (input | output) values inside of the <!ELEMENT nds> parenthesis define what kind of children it can have, how many of those children it can have, and its relationship to them. By the way, DTD is case sensitive.

First of all, notice that source has a ? symbol following it. The ? symbol means that an <!ELEMENT nds> is allowed to have zero or one child nodes with the name source.

Below is a table showing the other characters used to define child node count in an <!ELEMENT>:

Child Count Explanation
?
specifies zero or one child node
+
specifies one or more child nodes
*
specifies zero or more child node
none
specifies exactly one child node

Next, notice the nested subexpression, (input | output). This simply means that an <!ELEMENT nds> can also have either an input or an output child.

So, an <!ELEMENT nds> can have zero or one source node and then must have either a single input child node or a single output child node. An input operation would look like this:


<nds>
<source>
</source>
<input>
</input>
</nds>

<!ATTLIST> Elements

As you know, XML elements often have attributes. The <!ATTLIST> element describes the particular attribute names and values that are allowed for a particular <!ELEMENT>. For example, NDS.DTD defines the <!ATTLIST> below for <!ELEMENT nds>.


<!ELEMENT nds (source?, (input | output))>
<!ATTLIST nds
ndsversion CDATA #REQUIRED
dtdversion CDATA #REQUIRED >

Notice that the ndsversion and dtdversion attributes in the <!ELEMENT nds> example above are defined as #REQUIRED. This means that these attributes are required in each <!ELEMENT nds>, which of course will always be in an XDS document, because it is the topmost element defined in the NDS.DTD. The possible attribute default specifiers that we are concerned with are listed in the table below.

#REQUIRED
Specifies that the parser must insist that the specified attribute always be in the element.
#IMPLIED
Specifies that the parser should allow the attribute to exist without a value so that the XML application can add one later (if it so chooses).
#FIXED
Specifies that all attribute values of this kind must equal the value specified by this declaration.

Also notice that both of these attributes are defined to be of type CDATA, or character data. The attribute types in NDS.DTD that we need to be concerned with here are the following:

CDATA
Specifies character data (a similar type is PCDATA or parsed character data). For our purposes CDATA and PCDATA can be treated identically.
ENTITY
Specifies a reference to an entity (see <!ENTITY> declaration above) to be inserted as a constant value for the attribute.
ID or IDREF
Specifies that the attribute must have a unique value associated with it. For example, an attribute describing an automobile part might be defined in a DTD like this:
<!ATTLIST part number IDREFS #REQUIRED/> .

... which could then describe some XML that might look something like this:
<part number="35"/>

Every other part attribute in the XML document would then be required to have a different number than "A35".
NMTOKEN
Specifies that there can be no spaces in the attribute value. A DTD using NMTOKENS might look like this:
<!ATTLIST part number NMTOKEN #REQUIRED/>

... which might then describe some XML like this:
<part number="A35"/>

A similar type is NMTOKENS which is used to indicate multiple values, each with white space delimiting it. A DTD using NMTOKENS might look like this:
<!ATTLIST part numbers NMTOKENS #REQUIRED/>

... which might then describe some XML like this:
<part numbers="A35 S231 E17"/>

Building an Empty Input XDS Document

This section shows how to format a simple input XDS document from sample data.

Sample Data

dtd version
1.0
nds version
8.5
asn1 id
2 16 840 1 113719 1 x
version
1.0b3
product
DirXML
contact
Novell, Inc.


NDS.DTD Excerpts
<!ELEMENT nds (source?, (input | output))>
<!ATTLIST nds
ndsversion CDATA #REQUIRED
dtdversion CDATA #REQUIRED >

<!ELEMENT source (product?,contact?)>

<!ELEMENT product (#PCDATA)>
<!ATTLIST product
version CDATA #IMPLIED
asn1id CDATA #IMPLIED>

<!ELEMENT contact (#PCDATA)>

<!ELEMENT input (add|modify|delete|rename|move|query|query-schema|
add-association|modify-association|remove-association|
init-params|status)* >

How to Build an Empty XDS Document

Follow the steps below.

  1. First, create an nds element, since that is the parent element in every XDS document.

<nds>
</nds>

  1. Next, we know (from the Sample Data) that we need to add DTD and NDS version information to the document. The DTD line below tells us that an <!ELEMENT nds> must have this information added to it as attributes.

 <!ATTLIST nds
ndsversion CDATA #REQUIRED
dtdversion CDATA #REQUIRED >


<nds dtdversion="1.0" ndsversion="8.5">
</nds>

  1. Next, we know from the Example sample data that we need to add product name, product version, and contact information to the document. The optional source element is designated to contain product and contact information and the <!ELEMENT nds (source?, (input | output))> DTD line tells us that an <!ELEMENT nds> can have zero or one source node.

<nds dtdversion="1.0" ndsversion="8.5">
<source>
<product asn1id="2 16 840 1 113719 1 x" version="1.0b3">DirXML</product>
<contact>Novell, Inc.</contact>
</source>
</nds>

  1. Finally, we know from the <!ELEMENT nds (source?, (input | output))> DTD line, that an nds element must have either a single input child node or a single output child node. So, we'll add an input node to the document.

<nds dtdversion="1.0" ndsversion="8.5">
<source>
<product asn1id="2 16 840 1 113719 1 x" version="1.0b3">DirXML</product>
<contact>Novell, Inc.</contact>
</source>
<input>
</ input >
</nds>

Q. How many immediate children can <input> have?

A. As many as you need.The inside of the parenthetical statement for NDS.DTD's input element declaration (shown below) says that an input element must have exactly one of any of the elements named as possible children.

However, the '*' character after the closing parenthesis says that once the parenthetical statement is resolved, you can have from zero to as many as you want of those resolved parenthetical statements.


<!ELEMENT input	 (add|modify|delete|rename|move|query|query-schema|
add-association|modify-association|remove-association|
init-params|status)* >

Note: All of the input elements shown in the DTD line above are possible events that can be sent either from eDirectory to the external system or from the external system to eDirectory for synchronization. If the receiving system needed to send a response to the event, it would build an XDS document containing an output element and send it the opposite direction.

Building an Add Event XDS Document

Now, it's your turn to build an add event XDS document from some sample data using some excerpts from NDS.DTD.

Hints:

Sample Data

dtd version
1.0
nds version
8.5
asn1 id
2 16 840 1 113719 1 x
version
1.0b3
product
DirXML
contact
Novell, Inc.
event
add
class
user
association
0199
src-dn
0199
firstName
Lab1Engineer
lastName
CodeBrain
department
Engineering
location
Provo
phone
222-1234
title
Implementor of Piciune Software Details


NDS.DTD Excerpts
<!ENTITY % Assoc-State
"not-associated|associated|disabled|migrate|pending|manual">
<!ENTITY % Attr-type
"string|teleNumber|int|state|counter|dn|interval|octet|time|structured">
<!ENTITY % Boolean "true | false">

<!ELEMENT nds (source?, (input | output))>
<!ATTLIST nds
ndsversion CDATA #REQUIRED
dtdversion CDATA #REQUIRED>

<!ELEMENT source (product?,contact?)>

<!ELEMENT product (#PCDATA)>
<!ATTLIST product
version CDATA #IMPLIED
asn1id CDATA #IMPLIED>

<!ELEMENT contact (#PCDATA)>

<!ELEMENT input (add|modify|delete|rename|move|query|query-schema|
add-association|modify-association|remove-association|
init-params|status)* >

<!ELEMENT add (association?, add-attr*, password?)>
<!ATTLIST add
src-dn CDATA #IMPLIED
src-entry-id CDATA #IMPLIED
dest-dn CDATA #IMPLIED
dest-entry-id CDATA #IMPLIED
class-name CDATA #REQUIRED
template-dn CDATA #IMPLIED
event-id CDATA #IMPLIED>

<!ELEMENT association (#PCDATA)>
<!ATTLIST association
state (%Assoc-State;) #IMPLIED>


<!ELEMENT add-attr (value+)>
<!ATTLIST add-attr
attr-name CDATA #REQUIRED>

<!ELEMENT value (#PCDATA | component)*>
<!ATTLIST value
type (%Attr-type;) #IMPLIED
association-ref CDATA #IMPLIED
naming (%Boolean;) "false">

<!ELEMENT component (#PCDATA)>
<!ATTLIST component
name CDATA #REQUIRED
association-ref CDATA #IMPLIED>


<!ELEMENT password (#PCDATA)>

Exercise

Use the NTS.DTD excerpts above to construct an input XDS document which communicates the information in the Sample Data section above. Try to develop the document without referring to the following answer.


<nds dtdversion="1.0" ndsversion="8.5">
<source>
<product asn1id="2 16 840 1 113719 1 x" version="1.0b3">DirXML</product>
<contact>Novell, Inc.</contact>
</source>
<input>
<add class-name="User" src-dn="0199">
<association>0199</association>
<add-attr attr-name="firstName">
<value type="string">Lab1Engineer</value>
</add-attr>
<add-attr attr-name="lastName">
<value type="string">CodeBrain</value>
</add-attr>
<add-attr attr-name="department">
<value type="string">Engineering</value>
</add-attr>
<add-attr attr-name="location">
<value type="string">Provo</value>
</add-attr>
<add-attr attr-name="phone">
<value type="telenumber">001-5565</value>
</add-attr>
<add-attr attr-name="title">
<value type="string">Software Engineer</value>
</add-attr>
</add>
</input>
</nds>

Conclusion

Well, now you are able to use NDS.DTD to write XDS documents to communicate directory event information. This ability is essential so that you can determine the legitimate composition of XDS documents before you write code to build them using DirXML stylesheets or driver shims.

You will find an updated version of this article in the form of a lab in the DirXML Custom Driver Development course on the DeveloperNet web site at: http://developer.novell.com/servlet/devnet/education/index.html.

Copyright ©2001 by Novell, Inc. All rights reserved. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, for any purpose without the express written permission of Novell.

All product names mentioned are trademarks of their respective companies or distributors.



 
  REDESIGN INFO  |  SITE INDEX  |  LEGAL ©2000 NOVELL, INC.  |  PRIVACY  |  FEEDBACK