xsl-list
[Top] [All Lists]

RE: Parameterizing an XML using a XSLT

2003-04-09 07:33:16
I might not have your exact requirements correct, but try replacing your
Reference template with the following:

<xsl:template match="Reference">
  <xsl:choose>
    <xsl:when test="preceding-sibling::Command='Add'">
      <Reference>
        <xsl:copy-of select="@*" />
        (ref<xsl:value-of 
select="count(../preceding-sibling::Status[Command='Add'])+1" />)
      </Reference>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="." />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
  
<xsl:template match="Loc">
  <Loc>
    <xsl:copy-of select="@*" />
    (ref<xsl:value-of 
select="count(../../../preceding-sibling::Status[Command='Add'])" />)
  </Loc>
</xsl:template>

There are probably far most elegant solution though!

Regards

Bryan

-----Original Message-----
From: Scott H Snyder [mailto:shsnyder(_at_)us(_dot_)ibm(_dot_)com]
Sent: 09 April 2003 14:58
To: XSL-List(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Parameterizing an XML using a XSLT






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
Visit our website at http://www.rm.com

This message is confidential.  You should not copy it
or disclose its contents to anyone.  You may use and apply the information
only for the intended purpose.  Internet communications are not secure and
therefore RM does not accept legal responsibility for the contents of this
message.  Any views or opinions presented are only those of the author and
not those of RM.  If this email has come to you in error please delete it
and any attachments.  Please note that RM may intercept incoming and
outgoing e-mail communications.

This email has been scanned for viruses by Trend ScanMail.

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



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