[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: RE: Declarative programming requires a different mindset

  • From: Hermann Stamm-Wilbrandt <STAMMW@de.ibm.com>
  • To: xml-dev@lists.xml.org
  • Date: Mon, 22 Mar 2010 09:30:26 +0100

Re:  RE: Declarative programming requires a different mindset
Hi,

I learned from a colleague that changing namespaces is preferably
done by a modified copy stylesheet (no need to use "document()").
Find below a sample for just changing the default namespace (no prefix):

$ cat change.xsl
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" />

  <xsl:template
    match="*[namespace-uri()='http://www.example.com/v30']">
    <xsl:element name="{name()}"
      namespace="http://www.example.com/v31">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

$ cat data.xml
<profileRequest xmlns="http://www.example.com/v30">
  <profileID>1234567</profileID>
  <aSequence>1</aSequence>
  <timeStamp>2010-03-22T09:13:45Z</timeStamp>
</profileRequest>

$ java -jar saxon9he.jar -xsl:change.xsl -s:data.xml -versionmsg:off ; echo
<?xml version="1.0" encoding="UTF-8"?><profileRequest
xmlns="http://www.example.com/v31">
  <profileID>1234567</profileID>
  <aSequence>1</aSequence>
  <timeStamp>2010-03-22T09:13:45Z</timeStamp>
</profileRequest>
$


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler, L3
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


                                                                           
             "Costello, Roger                                              
             L."                                                           
             <costello@m...                                          To 
             rg>                       "xml-dev@lists.xml.org"             
                                       <xml-dev@lists.xml.org>             
             03/20/2010 05:35                                           cc 
             PM                                                            
                                                                   Subject 
                                        RE: Declarative           
                                       programming requires a different    
                                       mindset                             
                                                                           
                                                                           
                                                                           
                                                                           
                                                                           
                                                                           




Hi Folks,

The imperative mindset dies hard.

Yesterday I wrote an XSLT transform. I was very proud of it. This morning I
realized that I had written it imperatively. Oops!

I re-wrote it, in a declarative fashion. I'd like to share with you the
imperative version and then the declarative version.

Perhaps you've had a similar experience? Would you show how you started
with an imperative implementation and then re-worked it into a declarative
implementation?


Problem: create an XSLT transform that changes an XML document's namespaces
and prefixes.

Example: Suppose an XML document uses these namespaces:
    - http://www.secret-domain.org
    - http://www.temperature.org

And it uses these namespace prefixes:
    - Secret
    - Temp

My XSLT transform maps each namespace to a new namespace, e.g.,

Change:
    - http://www.secret-domain.org
to:
    - http://www.namespaces.org/NS1/

My XSLT also creates a new namespace prefix, e.g., change the prefix,
Secret, to the prefix, NS1.

Here's a sample XML document:

<Secret:Weather xmlns:Secret="http://www.secret-domain.org">
    <Secret:Location>Atlantistan</Secret:Location>
    <Secret:Date>2009-09-30T12:26:00</Secret:Date>
    <Temp:Temperature xmlns:Temp="http://www.temperature.org">
        91
    </Temp:Temperature>
</Secret:Weather>


Here's the output of my XSLT transform:

<NS1:Weather xmlns:NS1="http://www.namespaces.org/NS1/">
    <NS1:Location>Atlantistan</NS1:Location>
    <NS1:Date>2009-09-30T12:26:00</NS1:Date>
    <NS2:Temperature xmlns:NS2="http://www.namespaces.org/NS2/">
        91
    </NS2:Temperature>
</NS1:Weather>

Notice that the namespaces and prefixes have been changed.

I used XSLT 1.0 to implement this.


VERSION #1 (IMPERATIVE MINDSET)

I created two string variables, one to hold the namespaces of the input XML
document and a second variable to hold the namespaces of the output XML
document (and I prefixed the latter namespaces):

<xsl:variable name="input-document-namespaces"
              select="'http://www.secret-domain.org
                       http://www.temperature.org'"/>

<xsl:variable name="use-these-namespaces"
              select="'NS1:http://www.namespaces.org/NS1/
                       NS2:http://www.namespaces.org/NS2/'"/>

I wrote an XSLT named template to walk down the two string variables in
parallel. My "list walking" code is at the end of this message.

"Walk down two lists" ... that's an imperative mindset. Oops!


VERSION #2 (DECLARATIVE MINDSET)

This morning I remembered a fabulous technique that I learned from Dimitre
Novatchev.

Rather than creating string variables, create some XML and insert it
directly into the XSLT transform document:

<f:namespace-mappings>
    <f:namespace-map>
        <f:input-document>
            <f:namespace>
                http://www.secret-domain.org
            </f:namespace>
        </f:input-document>
        <f:output-document>
            <f:namespace>
                http://www.namespaces.org/NS1/
            </f:namespace>
            <f:prefix>
                NS1
            </f:prefix>
        </f:output-document>
    </f:namespace-map>
    <f:namespace-map>
        <f:input-document>
            <f:namespace>
                http://www.temperature.org
            </f:namespace>
        </f:input-document>
        <f:output-document>
            <f:namespace>
                http://www.namespaces.org/NS2/
            </f:namespace>
            <f:prefix>
                NS2
            </f:prefix>
        </f:output-document>
    </f:namespace-map>
</f:namespace-mappings>

Note: the XML must be in a namespace other than the XSL namespace. I placed
this namespace declaration at the top of my XSLT document:

    xmlns:f="f:8B9C63F4-F4AB5D11-994A0001-B4CD626F"

The XML contains a <namespace-map> element for each input namespace. It
maps an input namespace to the desired output namespace and to a prefix.
For example, it maps this input namespace:

    http://www.secret-domain.org

to this output namespace:

    http://www.namespaces.org/NS1/

and to this prefix:

    NS1:


Suppose the value of a variable, $ns, is an input namespace (such as
http://www.secret-domain.org). The output namespace and prefix is obtained
simply by looking them up in the XML:

<xsl:variable name="namespace-map"
     select="document('')/*//f:namespace-map
         [f:input-document/f:namespace=$ns]" />

<xsl:variable name="use-this-namespace"
      select="$namespace-map/f:output-document/f:namespace" />

<xsl:variable name="use-this-prefix"
      select="$namespace-map/f:output-document/f:prefix" />

Recap: the mappings are in XML. Select the desired values simply by
navigating the XML.

That's declarative. That's ultra cool.

I am very pleased with my new, declarative, XSLT transform. It is:

1.           Shorter than the imperative version.
2.           Much easier to understand.

/Roger


IMPERATIVE CODE THAT WALKS TWO LISTS IN PARALLEL

In parallel, walk down list1 and list2. Upon finding list1-value (in
list1), return the corresponding value in list2.

<xsl:template name="walk-two-lists">
    <xsl:param name="list1" />
    <xsl:param name="list2" />
    <xsl:param name="list1-value" />

    <xsl:choose>
        <xsl:when test="$list1 = $list1-value">
            <xsl:value-of select="$list2" />
        </xsl:when>
        <xsl:when test="substring-before($list1, ' ') = $list1-value">
            <xsl:value-of select="substring-before($list2, ' ')" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="walk-two-lists">
                <xsl:with-param name="list1"
                           select="substring-after($list1, ' ')" />
                <xsl:with-param name="list2"
                           select=" substring-after($list2, ' '))" />
                <xsl:with-param name="list1-value"
                          select="$list1-value" />
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>

</xsl:template>

_______________________________________________________________________

XML-DEV is a publicly archived, unmoderated list hosted by OASIS
to support XML implementation and development. To minimize
spam in the archives, you must subscribe before posting.

[Un]Subscribe/change address: http://www.oasis-open.org/mlmanage/
Or unsubscribe: xml-dev-unsubscribe@lists.xml.org
subscribe: xml-dev-subscribe@lists.xml.org
List archive: http://lists.xml.org/archives/xml-dev/
List Guidelines: http://www.oasis-open.org/maillists/guidelines.php





[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index]


PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
 

Stylus Studio has published XML-DEV in RSS and ATOM formats, enabling users to easily subcribe to the list from their preferred news reader application.


Stylus Studio Sponsored Links are added links designed to provide related and additional information to the visitors of this website. they were not included by the author in the initial post. To view the content without the Sponsor Links please click here.

Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.