[Home] [By Thread] [By Date] [Recent Entries]

Subject: [Part 1] Data-driven design and onion-skin layering: a better way to build systems
From: "Roger L Costello costello@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 20 Apr 2026 22:44:09 -0000
Hi Folks,
I$B!G(Bd like to share a refinement of a question I posed recently about
declarative vs imperative programming.
Originally, I framed the issue like this:
Which is a better way to design a system: declarative or imperative?
After the helpful responses from Ken Holman and others, I think that is not
quite the right question.
A more useful way to think about it is this:
How do you structure a system so that data drives the output, shared behavior
is centralized, while variation is handled cleanly and locally?
That reframing leads to two ideas that, taken together, clarify where XSLT is
especially strong.
________________________________
Data-driven vs program-driven
Every introductory programming text shows:
input $B"*(B program $B"*(B output
At a high level, that is true for every system.
But it hides an important distinction.
In many imperative systems, the program controls the flow and pulls data as
needed. The developer decides:

  *   what to do next
  *   when to iterate
  *   when to branch
  *   how to traverse the input
The logic is program-driven.
In XSLT, the model is different. The structure of the input determines what
processing occurs. Templates match nodes, and the system reacts to the data.
The logic is data-driven.
It$B!G(Bs not that imperative systems cannot be written in a push-like
style-they can-but doing so requires explicit orchestration. In XSLT, this
model is intrinsic: pattern matching and template application make the input
itself the driver of processing.
This is why XSLT is particularly effective when output is largely determined
by structured input (publishing, reporting, transformation, etc.).
________________________________
Why XSLT often doesn$B!G(Bt $B!H(Bfeel$B!I(B declarative
Many developers encountering XSLT for the first time do not experience it as
declarative. They see constructs that resemble familiar imperative concepts:

  *   iteration
  *   functions
  *   recursion
  *   conditional logic
and they map them mentally onto loops and control flow.
That reaction is understandable, but it misses the underlying model.
The real difference is not the absence of constructs that resemble imperative
ones. The real difference is how the system is organized.
In imperative code, the program dictates each step:

  *   get the next item
  *   test it
  *   branch
  *   call helper logic
  *   continue
In XSLT, the stylesheet declares:

  *   when this kind of node appears, here is its behavior
  *   when that kind of node appears, here is its behavior
  *   otherwise, use the default behavior
That is a different way of structuring a system.
________________________________
Onion-skin layering (core + specialization)
Data-driven processing is only part of the story.
The second key idea is the onion-skin layering model:

  *   a shared core stylesheet defines default behavior
  *   outer layers import the core
  *   each layer overrides or augments only what needs to change
This allows:

  *   shared behavior to remain centralized
  *   variation to remain local
  *   the core to remain stable and reusable
A particularly important aspect (as Ken pointed out) is that an importing
layer can intercept the processing of input before the core$B!G(Bs default
behavior applies.
The core can be completely unaware that specialization is taking place.
The specialization layer reacts first. The core then applies its default
behavior, unaware that anything has been overridden or augmented.
This allows the core to be treated as read-only, sacrosanct code, while outer
layers adapt behavior for different consumers.
This is not just a convenience feature-it is a deep architectural capability.

Current Thread
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member