DXL Tutorial – Part I

I’ve seen a few DXL guides in my day, and I’ve seen a lot of DXL snippets, but I’ve never seen an in-depth DXL tutorial. I’m writing this to help plug a gap in the world of DOORS and DXL.

DXL coding is like coding in any other type of language, you have to practice it and do it over and over and over again until you learn its intricacies. The problem that DXL has, unlike many languages, is that it only has a reference guide, and not a full API manual. The reference guide assumes that the programmer is only using the guide as a reference, so explanations are generally on the shorter side, and details are generally not always given where they ought to be.

Telelogic wants to sell training, and that’s fine, but in my opinion, they cripple their user guides as a result. I think they could put every ounce of information about DOORS and DXL in their documentation and they would still sell training, as most projects have managers that understand the importance of getting requirements right the first time.

There I go, digressing again.

The reason I bring it up in the first place is that there are just many different places to go to find critical information. Why isn’t the DXL I wrote showing up in my user menu? Why am I getting an error on a print statement? Finding the answers to these questions takes a lot of time, as you may find them on the Telelogic forums, in the reference guide, via a Google search or by studying code yourself, but there isn’t just one or two single places to go.

The purpose of this series is to take a relatively simple script and add on to it and make it robust, providing a great DXL tutorial in the process. I shall do my best to document the reason for every single line of code.

I was recently tasked with finding out which modules in our database have incoming links. So I wrote a simple function to accomplish the task. This series will take that function and expand upon it incrementally, giving it more features.

Please leave me comments and ask as many questions as possible. Also, make some requests for features. We can all try to build this together. Remember, the goal here is to document as much as possible in an easy tutorial—so people can look at this example and see all the basics to lookout for in one place.

I do assume that you have a basic understanding of programming. This isn’t about teaching programming. You should know the difference between an int and a string. You should know the difference between a for loop and a while loop. If you know the basics–if statements, Boolean logic, etc, you will likely be able to learn some DXL from this tutorial.

So without further ado, let’s begin.

For now, I am setting our goal to be finding out if the current module has any objects that contain incoming links. This seems pretty easy overall. We will eventually expand upon it and include every module in a folder, but for right now, we’re going to concentrate on just the current module.

Thus, step one is to open a module.

The first thing to get out of the way is how to format the comments at the beginning of the file. This header information is important in case someone else has to maintain our DXL and/or we ever want to put it in a DOORS menu.

If we want to use this in a DOORS DXL menu, our code must begin with each of the comment styles, in this order.



You can run any DXL you want without this at the beginning, but it will never show up in a DOORS menu.

So I’m going to populate this code.

//Module has incoming links.dxl

$FILENAME: Module has incoming links.dxl
$DATE_MODIFIED: 2007-09-23
The purpose of this DXL is to report whether the current module has any objects with incoming links.
2007-09-23: Initial Release

DXL, like C and C++, uses // and /* */ for comments. You can put anything you like in here and you’ll never get errors. The // is for a single line and /* */denotes multi-line comments.

So we’ve got our description. We should save the file as “Module has incoming links.dxl”.

Now let’s actually start some coding.

For now, the requirement is only to determine whether or not any objects have incoming links. We don’t need to count the number of objects, nor do we need any additional link information.

We have two methods of accomplishing this. We can look at every single object in the module one-by-one, or we can apply a filter. The better way to accomplish this is to apply a filter. Before we apply it, we have to define it.

//Declare filter integers for accepted and rejected objects
int iAcc = 0
int iRej = 0

//Turn off current filter
filtering off

//Define the filter
Filter f = hasLinks( linkFilterIncoming, "*" )

The above code will not give any errors in DOORS, but it won’t give any output either. However, I want to discuss what has already been done.

I declared integer variables for the number of objects accepted and rejected by the filter. This is necessary because if 0 objects are accepted, then our module has no objects with incoming links, and we need to know that. We likely won’t use the iRej variable, but we need it because the function that sets the filter requires it. I also initialize the variable because it’s just good practice. Without initializing it first, if I were to say, print iAcc, and it didn’t have a value, the user would get a DXL error.

Notice, also, how DOORS does not end statements with a semicolon. This makes it different than many other languages. If you don’t like this, you may put a semicolon at the end of every statement. DOORS will ignore it, but will still run DXL.

I did turn filtering off in case there is a filter applied. I do this because DOORS can be quirky sometimes and it’s best to be as explicit as possible. I believe you may omit this statement and the code will still work flawlessly, but I prefer to be safe when it comes to DXL.

Finally, notice where we define the actual filter. Notice that Filter is capitalized. When we declared integers, int was not capitalized. The reason for this is that DXL custom types are capitalized. In C, there are strings, reals, ints, bools, etc. If it exists in standard C, then it is not capitalized in DXL. The filter type is not found in C, so Filter must be capitalized, as must other DXL types, such as Module, Link, Object, and so forth.

There is a function for a filter called hasLinks. If you reference the DXL manual, you’ll see that you can filter on linkFilterIncoming, linkFilterOutgoing, or linkFilterBoth. These values correspond to the values in the links tab of the define filter dialog in DOORS.

The “*” means that we are ignoring specific link modules. Instead, we just want to know if there are any incoming links, regardless of which link module those links may be going through. If we wanted to look at a specific link module, the line would change to:

Filter f = hasLinks( linkFilterIncoming, “/path/to/link module/actual link module name” )

Is everyone with me so far? Now we just need to set the filter and turn filtering on and see what we get.

//set filter
set( current Module, f, iAcc, iRej)

The above code sets the filter f in the current Module. It passes the variables iAcc and iRej by reference, so that both iAcc and iRej are updated with the results. (The & symbol in front of iAcc and iRej in the DXL reference manual for this function means that these variables will get updated by the function).

At this point, we could turn filtering on with a line that said, “filtering on,” but there is no need to do so. We have the information we need. You can turn filtering on if you want to do a quick check, as every object should have at least one incoming link.

If any objects were accepted, we know we have incoming links. So we just need to print out whether we do.

( iAcc > 0 ) ? print "true" : print "false"

This is a unary if statement. Since we’re just wanting to do something simple, we can use this method. It is equivalent to the following code.

if ( iAcc > 0 ) {
print "true"
} else {
print "false"
}//end if

The above code, whichever if statement method is used, will print out true or false in the DXL Interaction window, even if the DXL Interaction window is not being displayed. Calling print will always display it.

Since this may be a menu option one day, we shouldn’t use the print statement. So I’m going to change the code.

( iAcc > 0 ) ? ack "true" : ack "false"

Ack is equivalent to msgBox for you VB programmers out there. It displays a dialog box with an OK button. It’s more interactive and user friendly. (I apologize for using buzzwords from the 1990s, but in this case, it’s true. An ack box is generally better to use than a print statement in DXL.)

So for now, we’re done. I’ve included the entire code below. We’re going to add on to it. My plans eventually are to choose an individual module to run this on via a dialog box. Then maybe to choose a folder to run this on. Finally we may output a report to Microsoft Excel. And we’ll do it from scratch.

Next time we’re going to talk about making the above code into a function. This will let us reuse the code in other scripts very easily.

If anyone has any ideas on how to enhance this, or what tutorial features you’d like to see, feel free to comment below.

//Module has incoming links.dxl


$FILENAME: Module has incoming links.dxl
$DATE_MODIFIED: 2007-09-24
The purpose of this DXL is to report whether the current module has any objects with incoming links.

2007-09-24: Initial Release


//Declare filter integers for accepted and rejected objects
int iAcc = 0
int iRej = 0

//Turn off current filter, in case there is one already applied
filtering off

//Define the filter
Filter f = hasLinks( linkFilterIncoming, "*" )

//set filter
set( current Module, f, iAcc, iRej)

( iAcc > 0 ) ? ack "true" : ack "false"

To run this, in the module you’ve opened, choose Tools>DXL Interaction, paste the code, and click Run.


  1. Here are my questions:
    (1) What namespace does the script run in? Reason for the question has to do with filter off, and setting it to something else. What if it was on and set to something important in a shared namespace. You would have to do this:
    save filter in foo
    setup a new filter
    run with new filter
    …. do something with the results ….
    restore filter from foo

    (2) Are spaces after parens for readability?

    (3) What is the scope of * in
    Filter f = hasLinks( linkFilterIncoming, “*” )
    This module, all modules, all folders, etc.

    (3) The & symbol in front of a var in a function call appears to mean “pass by reference”, but in your example the & is missing in the call. Passing by reference is the only way passed vars can be updated by a function (in other languages that I know). In a pass by value, the function gets what you sent and can’t change it because there is no reference.

    (4) You wrote: “You can turn filtering on if you want to do a quick check, as every object should have at least one incoming link.” Why should every object have an incoming link?

    (5) Explain “object” in the DOORS context. I know from prior use that it is whatever is saved in an attribute, but I want to hear it from you. And “whatever” is not very precise.

    I have a couple of suggestions:
    (1) That you number your paragraphs so that a reference can be made without quoting to create the context.

    (2) Make a distinction between “has to be” and “happens to be” – like the capitilization for Filter. Convention or required?

    Thanks for starting this tutorial. You can count on me reading every word.


  2. Mike,

    1. The term “namespace” isn’t really used in the DOORS DXL world, but if you want an answer, I’d say the namespace is the current module.

    The script can be modified to have a variable contain the current filter, then be run, then set that filter back. Something like:

    Filter fOriginal = current

    at the beggining of the script, then

    filtering off
    set ( m, fOriginal )
    filtering on

    at the end of the script, would accomplish what you want.

    Most of the time, filters are saved with views, so it is not a big deal that the filter goes away. And filters can be recreated.

    The other thing that this tutorial assumed is that the end user only wants to find out if there are links to the module. In this type of scenario, chances are the user opens the module, runs the script, then closes it.

    The tutorial isn’t focused on the end user quite yet. It’s more for the DXL coder.

    2. I have trained myself to put spaces after parenthesis for readability. That is certainly optional!

    3a. I think I said pass by value when I meant pass by reference! Good catch! I will fix that above.

    In the DXL manual, the function shows that it is declared like this:

    void set(Module m, Filter f [,int &accepted, int &rejected])

    But when called in DXL, you do not put the “&” symbol in front of the variables. You probably can, but there is no point.

    3b. I thought I explained this well, but apparently I did not.

    The “*” means “all link modules.” You may also put choose to not use “*” and only look at a specific link module by replacing “*” with “/path/to/Link Module”.

    Does that explain it better?

    4. Once we set the filter, if any objects are returned, they should all have an incoming link, because that is what the filter is set for. I did not mean that all objects in the module should have an incoming link; rather I meant all filtered objects should have at least one incoming link.

    5. Actually, your definition is not correct. So let me get in-depth.

    DOORS is a database. The database contains modules. Modules are comprised of attributes and objects. An object in DOORS is located in a module and consists of values of defined attributes. If you want to go down further, you could argue that objects also contain links, as links cannot exist without objects.

    To “get” an object in DXL, you must first have a module open. You can create an Object variable in DXL, but you cannot use that Object without a module in which it can reside. By default, DXL assumes that the Object you’re working with is within the “current” module.

    Regarding your suggestions…
    1. I am new to blogging and hopefully will be able to update my style sheet to automatically number lines in included code.

    2. In all fairness, above I said, “The filter type is not found in C, so Filter must be capitalized, as must other DXL types, such as Module, Link, Object, and so forth.”

    This is a “has to be.” If you type this in the DXL window:

    module m = current

    and click run, you will get an error.

    if you type this:

    Module m = current

    and click run, you will not.

    Keep the comments/questions and suggestions coming!

  3. Hey Kevin,

    First of all, nice ideia to log you experience and share it on the web, you´re helping a lot of people!!

    I´m beginner on DXL, and I need help, maybe you can gimme some ideas!

    When I execute my DXL script on its server, sometimes I receive a message like “an unexpected error has occurred, unexpected token. Failed to load index: xxx/xxx/views”

    It seems to be like a failure when reading any content that is loaded under a pre-set view.

    How can I run the DXL leaving views when opening contents?
    If I use “filtering off”, will DXL read the module as a “raw” thing, without those views?
    Will “filtering off” disable views for end-users that are used to load Doors and its windows and menus? I mean, will this command kill all views, so the users will need to reconstruct them?

    Does DXL accept recursive functions?
    BTW, is recursion more economic than loop, when talking about memory?

    And the last question: can you provide an email address from which I can message you?


  4. Mauro,

    You can write me at kevin.murphy at this domain name.

    I am not entirely sure why you are getting that view error–I don’t know if it is trigger-based or if it’s an error in the view or server corruption. Go to the doors forums at telelogic’s site and do some searches on trigger listing functions.

    You should get these same errors when switching views.

    Filtering off does not read the module “raw”…but it helps. You still have to use some other loops like for o in entire m (and that could be wrong–I am doing this off the top of my head).

    You can write recursive functions in DXL. Regarding memory–I am not sure if recursion is better for memory, but if you’re dealing with strings that all goes into DOORS’ leaky string table, so that won’t matter. It depends on what you are trying to do.

  5. When it comes to recursion it all depends on the algorithm and what you want to accomplish.

    For example, if you want to compute “n” factorial or the fibonacci sequence of “n” it is more efficient to develop an iterative function over a recursive one.

  6. Kevin,
    This is such a great idea, and well done for sharing with people of various levels of expertise. You explained a number of topics that I had been making guesses about as a casual DXL user. I belive that the approach of starting a simple program and using it to introduce new concepts is very sound.

    I am disappointed not to find Parts 2-n. Am I not looking in the right place, or have you given up on this?



  7. Salas,

    You need to give me the error message in order to help you out.

    My immediate guess is that you are using DOORS 7 or something. This will not work in versions of DOORS that do not use URLs.

    My second guess is that you didn’t run this from an open module. The code above needs to be run in an open module with an object selected.

    Good luck.

  8. Hey George and all—I’m still here and alive. It’s just that life has really gotten in the way of me maintaining this site as much as I like. I still have tons of opinions on DOORS and Requirements Management, but unfortunately have to focus on some personal items at the present time.

    I hope to expand and offer more tutorials soon.

  9. Hello Kevin,

    Its good that i have found this website. I am strugling with a some problem in dxl.

    My script portion is
    Module mod = read(fullName(anItem), false);

    It is failing every time it encounters the missing file view.ixc and giving run time error. Is there any method to avoid this problem such as if read fails continue with next iteration.

    please help me.


  10. Ravi,

    I don’t know why you’re getting the error on view.ixc, but I have some ideas for you.

    Are you sure that anItem is a module? anItem can be a Project or a Folder. You probably need an if statement, something like

    if (type(anItem) == “Formal”)

    Please note that I just made that if statement up. The function may not be type(), but you get the idea.

    Good luck.

  11. hi kevin ,
    i am new to this dxl script.
    can u help me out to write script.
    string s =” i shall go to movie , shall no, shall yes shall ,,shall”
    stiring sub= “shall”

    i need a program , how many shall are present in string.
    like above one it shd give 5 .
    irrespective of case.
    please help me out

  12. Hi Kevin,

    I have been investigating ways of showing link details (with the source/target content) between modules in a more efficient way than the graphical options available for a Link Module.

    Do you have any suggestions on how to edit the DXL to do show these relationships? Or are you aware of any addin scripts that already do this?

    Any assistance would be GREATLY appreciated! 🙂

    Thanks in advance,


  13. Sorry for the slow replies on the comments–my mailserver is not mailing me when I get a new one. Frustrating.

    skarthik: You need to use a regular expression, and there are limitations in the default implementation, but you should be able to get at least a few shalls. Still, you should only have one “shall” per object in DOORS.

    Dee: I need to know more details. I think you are talking about editing a link module to see details–does the analysis wizard view in a module not work for you?

    1. Yes, eventually. The problem as always is spare time. The good news is a client of mine wants me to develop some DXL training and has told me that I can use anything I develop for them for Baselines. So there will be something, and hopefully sooner rather than later.

Leave a Reply