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 14:03:37
Hi Roger,

One approach to a solution could be to write the transformation in an XSLT and 
have another XSLT stylesheet that transforms the XSLT into documentation for 
your clients. XSLT being XML can be transformed using XSLT.

There is a lot of flexibility in how XSLT code can be written to obtain the 
desired result (as is also the case with most languages). If you are able to 
create a consistent approach for yourself this could make it easier to create a 
XSLT stylesheet that transforms your XSLT into documentation, and could also 
make the transformation easier to maintain over time. You could even use a 
consistent way of writing comments in the XSLT to include descriptive text in 
the documentation. It may help if you can make each xslt:template instruction 
as small as it can be to handle a small part of the transformation.

This would involve a one time effort to convert your existing mapping document 
into XSLT code. This could be done by hand, but it sounds like you would be 
able to automate this process.

If you have oXygen XML Editor (there is a free trial available), the "Generate 
Documentation / XSLT Stylesheet Documentation" feature is one example of how 
this approach can look in action. 
https://www.oxygenxml.com/doc/versions/24.1/ug-editor/topics/documentation-XSLT-Stylesheet.html

Here is a small example that is based on the example that you provided:

Transformation XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl";
    exclude-result-prefixes="xd"
    version="3.0" expand-text="yes">

    <xd:doc>
        <xd:desc>Convert Published date string into DateOfPublication with 
Year, Month, Day elements</xd:desc>
    </xd:doc>
    <xsl:template match="Published">
        <DateOfPublication>
            <Year>{substring(., 1, 4)}</Year>
            <Month>{substring(., 5, 2)}</Month>
            <Day>{substring(., 7, 2)}</Day>
        </DateOfPublication>
    </xsl:template>

</xsl:stylesheet>

Documentation XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"; version="3.0" 
expand-text="yes">

    <xsl:output method="html"/>

    <xsl:template match="xsl:stylesheet">
        <html>
            <body>
                <h1>Transformation</h1>
                <xsl:apply-templates select="xsl:template"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="xsl:template">
        <xsl:variable name="filtered">
            <xsl:apply-templates select="node()" mode="filter"/>
        </xsl:variable>
        <h2>Source element: {@match}</h2>
        <xsl:apply-templates select="preceding-sibling::xd:doc[1]"/>
        <p>Transformation: <code>{serialize($filtered, map{'method': 'html', 
'undeclare-prefixes': true()})}</code></p>
    </xsl:template>

    <xsl:template match="xd:doc">
        <p>Description: {.}</p>
    </xsl:template>

    <xsl:template match="@* | node()" mode="filter">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@* | node()" mode="filter"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Cheers,
Vincent

_____________________________________________
Vincent M. Lizzi
Head of Information Standards | Taylor & Francis Group
vincent(_dot_)lizzi(_at_)taylorandfrancis(_dot_)com<mailto:vincent(_dot_)lizzi(_at_)taylorandfrancis(_dot_)com>



Information Classification: General
From: Roger L Costello costello(_at_)mitre(_dot_)org 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>
Sent: Thursday, April 21, 2022 12:37 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Seek your suggestions on how to create a declarative mapping 
document with embedded XSLT commands

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>