xsl-list
[Top] [All Lists]

Re: [xsl] Seek your suggestions on how to create a declarative mapping document with embedded XSLT commands

2022-04-21 12:16:49
There's nothing wrong with "little mapping languages" that do a well-defined 
simple job and do it well -- though they do sometimes run out of steam when 
people need to do something more complicated. And in this case the complexity 
of your language does seem to have grown rather. PHP started this way and was 
able to grow into a fully-fledged programming language because it was well 
designed in the first place, but other attempts like Freemarker turned into a 
mess as they grew because the syntax and semantics were not well thought out, 
and had to be redesigned with lots of incompatible changes. 

A good way to handle such languages is to write a stylesheet that converts them 
to XSLT and then execute the XSLT.

Michael Kay
Saxonica

On 21 Apr 2022, at 17:36, Roger L Costello costello(_at_)mitre(_dot_)org 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:

Hi Folks,

I have fallen into the trap of creating my own little mapping language and 
then writing an interpreter for my little language. I am hoping you can help 
me out of this trap and show me how to replace my little language with XSLT 
and use an XSLT processor.

Here's the background:

I am tasked to create a document which shows the mapping between one XML 
vocabulary and another. In addition, I need to implement a tool that performs 
the mapping, i.e., the tool takes an instance of the source XML vocabulary 
and generates an instance of the destination XML vocabulary, using the 
mapping document:

(source document, mapping document) --> tool --> destination document

Let's take a simple example. 

The source XML vocabulary has an element whose value is a date (YYYYMMDD):

<Published>20220421</Published>

The destination XML vocabulary has three elements, one containing a year 
(YYYY), a second containing a month (MM), and a third containing a day (DD). 
The three elements are enclosed within an element:

<DateOfPublication>
   <Year>2022</Year>
   <Month>04</Month>
   <Day>21</Day>
</DateOfPublication>

The mapping document must record that characters 1-4 of Published maps to the 
Year element in DateOfPublication, characters 5-6 maps to the Month element, 
and characters 7-8 maps to the Day element. 

Remember, in addition to the mapping document I need to write a tool that 
processes the mapping document to auto-generate a destination document. So in 
my mapping document I provide machine-processable instructions to the tool on 
how to perform the mapping:

<mapping>
   <row>
       <destination-element>DateOfPublication/Year</destination-element>
       <source-element>Published</source-element>
       <appinfo>
           <substring>
               <start>1</start>
               <length>4</length>
           </substring>
       </appinfo>
   </row>
   <row>
       <destination-element> DateOfPublication/Month</destination-element>
       <source-element>Published</source-element>
       <appinfo>
           <substring>
               <start>5</start>
               <length>2</length>
           </substring>
       </appinfo>
   </row>
   <row>
       <destination-element> DateOfPublication/Day</destination-element>
       <source-element>Published</source-element>
       <appinfo>
           <substring>
                <start>7</start>
                <length>2</length>
           </substring>
       </appinfo>
   </row>
</mapping>

"What's that appinfo element?" you ask. The appinfo element informs the tool 
how to do the mapping. For example, this appinfo:

       <appinfo>
           <substring>
               <start>1</start>
               <length>4</length>
           </substring>
       </appinfo>

informs the tool: get a substring of the source element (Published) starting 
at character 1 for a length of 4 and use it as the value of the destination 
element (DateOfPublication/Year).

That is a little language that I made up. The tool must be implemented to 
interpret my little language.

Ugh!

It would be better if I didn't invent a language.

It would be nice if I could use XSLT to express both the mapping as well as 
code for doing the mapping.

I could write an XSLT program like this:

<xsl:template match="/">
   <DateOfPublication>
       <Year><xsl:value-of select="substring($source/Published, 1, 
4)"/></Year>
       <Month><xsl:value-of select="substring($source/Published, 5, 
2)"/></Month>
       <Day><xsl:value-of select="substring($source/Published, 7, 2)"/></Day>
   </DateOfPublication>
</xsl:template>

But that's even worse than my mapping approach. Why? Because now the mapping 
is buried in code. My clients don't understand XSLT. At least my clients can 
understand my mapping (they ignore the appinfo part).

You might suggest, "Well, keep the mapping document (discard the appinfo 
part) and supplement it with the above XSLT program. That's even more worse. 
It has the mapping repeated in two places - in my mapping document and in 
XSLT code.

What I want is something like this:

<mapping>
   <row>
       <destination-element>DateOfPublication/Year</destination-element>
       <source-element>Published</source-element>
       <appinfo>
           <Year>
               <!-- XSLT code that maps characters 1-4 of Published to 
DateOfPublication/Year -->
          </Year>
       </appinfo>
   </row>
...

When I "run" that document, all the XSLT snippets get executed (by an XSLT 
processor).

Well, I think that's what would be really good, but I seek your suggestions. 
How to create a declarative mapping document with embedded XSLT commands?

/Roger


--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--


<Prev in Thread] Current Thread [Next in Thread>