Reputation: 57
I'm trying to help a friend solve a computer class take-home quiz. I have a simple XML file as follows which defines DVD titles I own on my shelf...
<Inventory>
<DVD>
<Name>Captain America</Name>
</DVD>
<DVD>
<Name>Green Lantern</Name>
</DVD>
<DVD>
<Name>Thor</Name>
</DVD>
</Inventory>
Let's say both "Captain America" and "Thor" are checked-out while "Green Lantern" is still available. I would like to transform the above XML file into the following XML...
<Inventory>
<DVD>
<Name>Captain America</Name>
<Status>Checked-Out</Status>
</DVD>
<DVD>
<Name>Green Lantern</Name>
<Status>Available</Status>
</DVD>
<DVD>
<Name>Thor</Name>
<Status>Checked-Out</Status>
</DVD>
</Inventory>
Can someone share how to utilize XSL to add the Status element to each node? I only have the code snippet below but it copies the same element for all nodes.
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DVD">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
<Status>Checked-Out</Status>
</xsl:copy>
</xsl:template>
Thank you very very very much...
Upvotes: 2
Views: 11226
Reputation: 52858
What you can do is use an xsl:param
to pass the name(s) of the DVD's that are checked out to your XSL and add the <status>
based on that. By using xsl:param
, you can pass the value from the command line.
Here's an XSLT 2.0 example where the DVD names are pipe delimited in the xsl:param
. I use tokenize()
in my xsl:template match
so that those DVD's get a status of "Checked-Out". All of the other DVD's will get the status of "Available".
XSLT 2.0 Stylesheet:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="checkedOut" select="'Captain America|Thor'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DVD[Name=tokenize($checkedOut,'\|')]">
<xsl:copy>
<xsl:apply-templates/>
<status>Checked-Out</status>
</xsl:copy>
</xsl:template>
<xsl:template match="DVD">
<xsl:copy>
<xsl:apply-templates/>
<status>Available</status>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
applied to your example XML produces the following output:
<Inventory>
<DVD>
<Name>Captain America</Name>
<status>Checked-Out</status>
</DVD>
<DVD>
<Name>Green Lantern</Name>
<status>Available</status>
</DVD>
<DVD>
<Name>Thor</Name>
<status>Checked-Out</status>
</DVD>
</Inventory>
Hope this helps.
Upvotes: 5