IBM DOORS provides a powerful scripting environment through DXL — DOORS Extension Language. With DXL, engineers can automate repetitive tasks, analyse requirements, manipulate modules and objects, process links, create reports, build custom dialogs, and extend the standard DOORS functionality.
However, DXL has its own syntax, data structures and programming concepts that can take some time to master.
This guide brings together a practical set of DXL techniques that can help both beginners and experienced DOORS users write more effective scripts.
Note: The examples in this article are intended as learning examples. Always validate DXL scripts in a controlled DOORS environment before using them on production data.
1. Working with Strings in DXL
String manipulation is one of the most common tasks when writing DXL scripts.
DXL allows different data types to be combined into strings. A simple example is printing a numeric value together with text:
real number = 4.123 print "The number is: " number ""
The empty string at the end is a common DXL technique when converting a value into text during concatenation.
Extracting part of a string
DXL supports substring operations using square brackets.
For example:
string text = "Hello world" string part1 = text[0:7] string part2 = text[5:] print part1 "\n" print part2 "\n"
You can also use variables or expressions inside the substring indexes:
int startPosition = 2 string text = "Hello world" print text[startPosition:(length(text)-4)]
This is particularly useful when processing requirement identifiers, filenames, attribute values or other structured strings.
2. Searching Within Strings
When processing requirements, you will frequently need to determine whether a particular word or phrase occurs inside an attribute.
For example, a script may need to identify requirements containing the word “shall”.
DXL provides string matching functions that can be used for this purpose.
Conceptually:
string requirementText = "The system shall monitor the temperature"
if (matches("shall", requirementText)) {
print "Keyword found"
}
This type of operation can be particularly useful when creating requirement-quality checks.
For example, you could search for:
- shall
- must
- TBD
- TBC
- optional
- interface
- safety
- verification
and generate a report identifying requirements requiring further review.
3. Converting Between Data Types
DXL scripts often need to convert information between strings and numeric types.
For example:
string value = "12.3" int integerValue = intOf(value) real realValue = realOf(value) char characterValue = charOf(integerValue)
This is useful when reading values from DOORS attributes, because attribute values are frequently handled as strings even when they represent numbers.
4. Comparing Dates
DXL provides a Date type that can be used when working with dates.
For example:
Date todayDate = today()
Date referenceDate = "1/1/2021 0:0:0"
if (todayDate > referenceDate) {
print "The reference date has passed."
}
Date comparisons can be useful for:
- requirement review dates
- approval dates
- project milestones
- verification deadlines
- document expiry checks
- change-management reports
5. Loops in DXL
Loops are fundamental when processing DOORS modules.
One form of loop is:
for i in 0 : 100 do {
print "Value: " i "\n"
}
A traditional loop can also be used:
int x
for (x = 0; x < 100; x++) {
print "Value: " x "\n"
}
When processing a DOORS module, however, you will frequently encounter object iteration:
Object obj
for obj in current Module do {
print identifier(obj) "\n"
}
This allows a script to process every object within a module.
6. Controlling Long-Running DXL Scripts
Large DOORS modules can contain thousands of requirements.
Consequently, a DXL script that processes every object, attribute or link can take considerable time.
pragma runLim, 0
where 0 is used to remove the normal execution limit.
However, this should be used carefully.
Removing a script timeout does not make the script faster. It simply allows the script to continue running indefinitely.
A better approach is usually to:
- Identify expensive operations.
- Avoid repeatedly opening the same module.
- Avoid unnecessary database operations.
- Use efficient data structures.
- Process only the objects that are actually required.
7. Understanding break, continue and halt
DXL provides several useful flow-control statements. Break Stops the current loop completely.
for (i = 0; i < 100; i++) {
if (i == 20) {
break
}
}
Continue Skips the remaining statements in the current iteration and moves to the next iteration.
for (i = 0; i < 100; i++) {
if (i % 2 == 0) {
continue
}
print i "\n"
}
Halt Stops execution of the DXL program.
These three commands are particularly useful when processing large modules.
8. Call by Value and Call by Reference
Understanding how parameters are passed to functions is important when writing reusable DXL functions.
A parameter passed by value represents a separate value within the function.
A parameter passed by reference can allow the function to modify the value outside the function.
This becomes useful when a function needs to return more than one piece of information.
For example, instead of returning only one result, a function can modify a referenced parameter and use the normal return value for another result.
This technique is useful for utility functions that perform calculations or process DOORS objects.
9. Static Arrays
Arrays are useful when working with collections of values.
For example:
string names[] = { "London", "Belfast", "Cardiff", "Edinburgh" }
In a real DOORS application, the array might contain:
- requirement IDs
- module names
- attribute names
- status values
- verification methods
- interface identifiers
10. Dynamic Arrays
DXL also provides dynamic arrays.
These are different from ordinary static arrays because they can contain different types of data.
A dynamic array can be created using:
Array data = create(1,1) put(data, "Example", 0, 0)
When the array is no longer required, it should be deleted:
delete(data)
One important consideration is memory management. Temporary data structures should not simply be created and forgotten.
1. Skip Lists — One of the Most Useful DXL Data Structures
If you work seriously with DXL, Skip lists are worth understanding.
A Skip list can be thought of as a key-value data structure, similar conceptually to:
- a HashMap in Java
- a Dictionary in C#
- an associative array in other languages
For example:
Skip myList = create put(myList, "REQ-001", "System requirement") put(myList, "REQ-002", "Software requirement")
You can check whether a key exists using find().
This is particularly useful for:
Removing duplicates
Suppose a module contains:
REQ-001 REQ-003 REQ-001 REQ-005 REQ-003
A Skip list can be used to create a unique collection.
Conceptually:
Skip uniqueRequirements = create
Then each requirement identifier can be inserted as a key.
Because the key must be unique, repeated identifiers can effectively be filtered out.
This makes Skip lists extremely useful for:
- duplicate detection
- unique requirement lists
- mapping IDs to objects
- lookup tables
- cross-reference reports
- link analysis
12. Using DxlObject with Skip Lists
For more complex applications, a Skip list can store DxlObject instances.
A DxlObject can be used to group several related values together.
13. Understanding current
One of the most important concepts in DOORS DXL is the current reference.
Depending on the context, current can refer to things such as:
- Project
- Folder
- Module
- Object
For example:
Project p = current Folder f = current Module m = current Object o = current
The meaning depends on what is currently selected in the DOORS interface.
You can also explicitly change the current context:
current = f
This becomes particularly important when navigating between folders, modules and objects.
DXL provides several functions for navigating the hierarchy of a module.
For example:
Object firstChild = first(obj) Object lastChild = last(obj) Object previousObject = previous(obj) Object nextObject = next(obj)
Sibling navigation is also possible:
firstSibling(obj) lastSibling(obj) nextSibling(obj)
These functions are extremely useful when writing scripts that understand the hierarchical structure of requirements.
For example, a script could determine:
- whether an object has children
- how many child requirements exist
- whether a requirement is the last object in a section
- which requirements belong to a particular parent
- how a requirement hierarchy is structured
15. Useful Object Information
Several DXL functions provide useful information about a DOORS object.
For example:
identifier(obj) number(obj) level(obj) leaf(obj)
These can provide information such as:
- DOORS object identifier
- hierarchical object number
- hierarchy depth
- whether the object has children
A simple reporting script might therefore use:
Object obj
for obj in current Module do
{
print number(obj) "\t"
print identifier(obj) "\t"
print obj."Object Heading" "\t"
print obj."Object Text" "\n"
}
This is a useful starting point for custom requirement reports.
16. Working with Links
Traceability is one of the most important capabilities of IBM DOORS.
DXL allows scripts to inspect both outgoing and incoming links.
For outgoing links, you can iterate through links associated with an object and obtain the target object.
Conceptually:
Link link
for link in obj -> "*" do
{
print fullName(target(link)) "\n"
}
This can be used to determine:
- how many outgoing links exist
- which modules are linked
- which requirements are downstream
- which verification objects are connected
17. Incoming Links and LinkRef
Incoming links require a slightly different approach.
The source module may need to be available before complete information about the source object can be obtained.
LinkRef is useful when initially examining incoming links because it can provide source-module information without requiring the complete source object immediately.
For example, you may first determine the source module:
LinkRef linkReference
for linkReference in obj <- "*" do
{
print fullName(source(linkReference)) "\n"
}
You can then open or read the relevant source module when the detailed source object information is required.
This technique is particularly useful for traceability reports across multiple requirement modules.
18. Baselines and Baseline Sets
It is important not to confuse a baseline with a baseline set.
A baseline represents a frozen version of a module.
A baseline set represents a coordinated frozen state involving multiple modules.
This distinction becomes important when developing DXL scripts for:
- configuration management
- change reporting
- traceability
- release management
- requirements comparison
19. Reading Module Attributes
DXL can be used to access module attributes.
For example:
Module m = read("/Project/System Requirements", true)
string moduleName = m."Name"
Module attributes can then be incorporated into automated reports.
This is useful when creating scripts that need to process modules without relying entirely on what the user has manually selected.
20. Modifying Module Attributes
If a module has been opened in edit mode, DXL can modify its attributes.
For example:
Module m = edit("System Requirements", true)
m."Description" = "Updated system requirements"
save(m)
close(m)
refreshDBExplorer()
When modifying DOORS data programmatically, however, scripts should be designed carefully.
A production script should consider:
- whether the module is already open
- whether another user is editing it
- whether the operation should be reversible
- whether the user has sufficient permissions
- whether the script should save automatically
21. Calculations in Layout DXL
Layout DXL is particularly useful when you want to calculate a value dynamically and display it in a module column.
For example, suppose a module contains:
Cost No per day
A Layout DXL column could calculate:
real cost int numberPerDay real result cost = obj."Cost" numberPerDay = obj."No per day" result = cost * realOf(numberPerDay) display result ""
This allows calculated information to be displayed alongside requirements without permanently storing the calculated value as an attribute.
Typical applications include:
- cost calculations
- risk calculations
- priority calculations
- effort estimates
- derived metrics
- verification statistics
22. Combining Filters and Sorting
DXL can also be used to programmatically apply filters and sorting.
For example, you might want to identify requirements where:
Cost > 1000 Cost < 2000 Object Text contains "shall"
Multiple filters can be combined.
Similarly, multiple sorting criteria can be chained, such as:
Cost — descending Priority — ascending
This becomes powerful when creating automated requirement-review tools.
Instead of manually filtering a module every time, a DXL script can apply a predefined analysis configuration.
23. Reading and Writing Files
DXL scripts can interact with external text files.
For example, a script can write data to a file:
Stream output = write("C:\\datafile.txt")
Object obj
real cost
for obj in current Module do
{
cost = obj."Cost"
output << cost "\n"
}
The resulting file can then be consumed by another tool.
DXL can also read files:
Stream input = read("C:\\datafile.txt")
string line
while (!end(input))
{
input >> line
print line "\n"
}
close(input)
This opens up possibilities for integration between DOORS and external analysis tools.
For example:
DOORS → DXL → Text/CSV → Python → Excel/Report
24. Creating DXL User Interfaces
DXL is not limited to command-line style scripts.
You can create custom dialog boxes using DB and DBE components.
A dialog can contain elements such as:
- text fields
- radio buttons
- sliders
- date controls
- buttons
- other input controls
For example:
DB dialog = create("Requirement Tool", styleStandard)
DBE nameField = field(
dialog,
"Requirement:",
"",
30,
false
)
show dialog
Callbacks can then be used to respond to user actions.
This is the foundation for building custom DOORS utilities with a proper user interface.
25. Error Handling
DXL scripts can encounter errors while accessing modules, objects, attributes or links.
Instead of allowing an error to interrupt the user with an unwanted DXL error window, error handling can be implemented using functions such as:
noError()
and:
lastError()
A simplified pattern is:
noError()
// Code that may generate an error
string errorMessage = lastError()
if (!null errorMessage)
{
infoBox errorMessage
halt
}
This gives the script developer more control over how errors are presented.
For production DXL utilities, meaningful error messages are much more useful than simply allowing a generic script failure to occur.
26. Checking Whether a String Is Numeric
Sometimes a DOORS attribute contains text that should represent a number.
A small helper function can be used to validate the contents before attempting numeric conversion.
For example, the logic can check each character to determine whether it is a digit or an accepted decimal/sign character.
This is useful before performing operations such as:
realOf(attributeValue)
Without validation, unexpected attribute content can result in errors or incorrect calculations.
27. Working with Permissions
DOORS environments can have complex access-control configurations.
In some situations, an object may inherit permissions from its parent.
DXL provides functions that can be used when working with inherited permissions.
However, permission-related scripts should be handled carefully because changing access behaviour can have significant consequences in a controlled requirements environment.
28. History and Discussions
DOORS maintains historical information associated with module changes.
Baselining plays an important role in how historical information is preserved.
The original Capri-Soft article also highlights Discussions, which provide a way for users to communicate about requirements within DOORS.
These capabilities can be useful when investigating:
- why a requirement changed
- who made a change
- review discussions
- change-management activities
- historical requirement decisions
29. Code Page Information
For environments where character encoding is important, DXL provides access to installed and supported code-page information.
This can be useful when diagnosing issues involving:
- special characters
- international text
- imported requirements
- exported files
- character encoding
Encoding problems can be particularly troublesome when requirements contain non-English characters or when data is exchanged with external systems.
30. Practical DXL Development Recommendations
The techniques above are useful individually, but they become much more powerful when combined into a disciplined development approach.
Keep scripts modular
Instead of creating one enormous DXL script, create reusable functions:
getRequirementText() getIncomingLinks() getOutgoingLinks() isNumeric() generateReport()
This makes the code easier to test and maintain.
Avoid repeatedly opening modules
Opening and closing modules repeatedly can significantly affect performance.
Where possible, determine which modules are required first and reuse existing references.
Clean up temporary objects
When using structures such as Arrays, Skip lists and Streams, release resources when they are no longer required.
For example:
delete(myList)
Validate attribute values
Never assume an attribute contains the expected data type.
For example, a “Cost” attribute might contain:
1250
but another requirement might contain:
TBD
Validate before converting or calculating.
Be careful with write operations
A script that only reads data is fundamentally different from one that modifies hundreds or thousands of requirements.
Before performing bulk modifications, consider:
- backups
- baselines
- permissions
- transaction/recovery strategy
- user confirmation
- logging
Conclusion
DXL becomes much easier to work with once you understand a relatively small set of core concepts.
The most important areas to master are:
- String manipulation
- Loops and flow control
- Arrays and Skip lists
currentand DOORS object navigation- Module and object attributes
- Incoming and outgoing links
- Filters and sorting
- File input/output
- Layout DXL
- User interfaces
- Error handling
- Baselines and configuration information
The real power of DXL comes from combining these capabilities.
For example, a single DXL application could:
Read a requirements module → analyse every requirement → inspect incoming and outgoing links → identify missing traceability → calculate metrics → generate a report → export the results to a file.
That is where DXL moves beyond being a scripting language and becomes a practical automation layer for IBM DOORS.
If you are working with DOORS on a regular basis, learning these patterns can significantly reduce repetitive manual work and allow you to build your own requirement-analysis, traceability and reporting utilities.
This post was published by Admin.
Email: admin@TheCloudStrap.Com
