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

Parameterizing an XML using a XSLT

Subject: Parameterizing an XML using a XSLT
From: Scott H Snyder <shsnyder@xxxxxxxxxx>
Date: Wed, 9 Apr 2003 09:57:38 -0400
xsl command reference



I am relatively new to XSLT so I am still trying to figure out how to move
from a procedural to functional mindset.
I have an XML file that I need to parameterize by replacing certain values
within tags with a placeholder.
This modified XML file will be sent to an external tool that will fill in
values for the placeholder at the appropriate time.

I would like to convert the first xml file below to the second one.  The
placeholders are written in () with a variable name in between.

Source File:
<Document>
    <Header>
        <ID>12345</ID>
    </Header>
    <Body>
        <Status>
            <Command>Test</Command>
            <Reference>11</Reference>
        </Status>
        <Status>
            <Command>Add</Command>
            <Reference>67</Reference>
        </Status>
        <Map>
            <MapItem>
                <Target>
                    <Loc>67</Loc>
                </Target>
            </MapItem>
        </Map>
       <Status>
            <Command>Test</Command>
            <Reference>22</Reference>
        </Status>
        <Status>
            <Command>Add</Command>
            <Reference>89</Reference>
        </Status>
        <Map>
            <MapItem>
                <Target>
                    <Loc>89</Loc>
                </Target>
            </MapItem>
        </Map>
    </Body>
</Document>

Desired Output:
<Document>
    <Header>
        <ID>(id)</ID>
    </Header>
    <Body>
        <Status>
            <Command>Test</Command>
            <Reference>11</Reference>
        </Status>
        <Status>
            <Command>Add</Command>
            <Reference>(ref1)</Reference>
        </Status>
        <Map>
            <MapItem>
                <Target>
                    <Loc>(ref1)</Loc>
                </Target>
            </MapItem>
        </Map>
        <Status>
            <Command>Test</Command>
            <Reference>22</Reference>
        </Status>
        <Status>
            <Command>Add</Command>
            <Reference>(ref2)</Reference>
        </Status>
        <Map>
            <MapItem>
                <Target>
                    <Loc>(ref2)</Loc>
                </Target>
            </MapItem>
        </Map>
    </Body>
</Document>

My XSL file simply copies everything from the source to the output until it
finds a node that matches a place that needs to be paramaterized, and
replaces that tag with the parameter.  But the transform currently falls
short in 2 areas:

1. It can place the placeholder in the //Status/Reference node if it has a
sibling of Command=Add but I cannot figure out a way of adding an index
number to the placeholder that increases sequentially for each match. Both
position() and <xsl:number > do not work with the transform constructed
this way.

2. How can I use the same placeholder in the //Map/MapItem/Target/Loc if
infact the number matches the one in the //Status/Reference tag above it.

If I could create a static counter that only got incremented when the
appropriate node in the file was found it would work but since XSLT does
not allow updating of variables I am not sure how to restructure the
transform to effectively do this.

If anyone has had to do a similar type of transform or has some pointers on
how to restructure the XSL file to do this I would appreciate any insight
you could provide.

Transform:
<?xml version="1.0"  ?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="iso-8859-1" indent="no"/>

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

        <xsl:template match="//Header/ID">
            <ID><xsl:copy-of select="@*" />(id)</ID>
      </xsl:template>

      <xsl:template match="//Body/Status/Reference">
            <xsl:choose>
                    <xsl:when test="preceding-sibling::Command='Add'">
                          <Reference><xsl:copy-of select="@*"
/>(ref)</Reference>
                  </xsl:when>
                  <xsl:otherwise>
                          <xsl:copy-of select="." />
                  </xsl:otherwise>
            </xsl:choose>
      </xsl:template>

</xsl:stylesheet>


Thanks in advance,

Scott

"The universe is driven by the complex interaction between three
ingredients: matter, energy, and enlightened self-interest."
    - G'Kar, Survivors





 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

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
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.