Subject: RE: How to delete empty element tag from output XML? From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Fri, 27 Oct 2000 10:48:30 +0100 |
Guangzu, >Thanks to Kay Michael and Jeni Tennison for your help. A general template is >what I am looking for. I wrote a template, it's more like a C function >except more awkward. Most of the codes is for print tag. I wish I can use ><xsl:element> to print the tag which is passed by parameter but don't know >how to assign the parameter to the name of element. With xsl:element, the @name attribute can take an attribute value template, so you can give computed values to the name of the element if you wrap the computed (part of) the name in {}s: <xsl:element name="{$tag}"> ... </xsl:element> You can do the same with attribute names as well. Actually, I used this in the template in my previous message: <xsl:template match="*"> <xsl:variable name="translation" select="..." /> <xsl:variable name="default" select="..." /> <xsl:choose> <xsl:when test="string(.)"> <!-- element added with the name given by $translation variable --> <xsl:element name="{$translation}"> <xsl:value-of select="." /> </xsl:element> </xsl:when> <xsl:when test="string($default)"> <xsl:element name="{$translation}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:when> </xsl:choose> </xsl:template> If you apply this to your template, then you get: <xsl:template name="empty_content"> <xsl:with-param name="content" /> <xsl:with-param name="tag" /> <xsl:with-param name="default" /> <xsl:if test="$content !=''"> <xsl:element name="{$tag}"> <xsl:value-of select="$content" /> </xsl:element> </xsl:if> <xsl:if test="$content = ''"> <xsl:if test="$default != ''"> <xsl:element name="{$tag}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:if> </xsl:if> </xsl:template> You can see that this is a lot cleaner than all those xsl:texts. I don't know what the xsl:with-params are doing there - they're illegal at that point (they're designed for being with an xsl:call-template or an xsl:apply-templates, to *pass* parameters). You meant xsl:param: <xsl:template name="empty_content"> <xsl:param name="content" /> <xsl:param name="tag" /> <xsl:param name="default" /> <xsl:if test="$content !=''"> <xsl:element name="{$tag}"> <xsl:value-of select="$content" /> </xsl:element> </xsl:if> <xsl:if test="$content = ''"> <xsl:if test="$default != ''"> <xsl:element name="{$tag}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:if> </xsl:if> </xsl:template> There are some other changes that you could make if you wanted to, and I'll step through them so that you can see the alternatives. When you have two xsl:ifs that test mutually-exclusive conditions side by side (as you do here), then you can turn it into an xsl:choose with an xsl:when and an xsl:otherwise instead: <xsl:template name="empty-content"> <xsl:param name="content" /> <xsl:param name="tag" /> <xsl:param name="default" /> <xsl:choose> <xsl:when test="$content != ''"> <xsl:element name="{$tag}"> <xsl:value-of select="$content" /> </xsl:element> </xsl:when> <xsl:otherwise> <xsl:if test="$default != ''"> <xsl:element name="{$tag}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:if> </xsl:otherwise> </xsl:choose> </xsl:template> When you have a xsl:otherwise with an xsl:if inside it as the only content, then you can turn it into an xsl:when with the test from the xsl:if to give the same effect: <xsl:template name="empty-content"> <xsl:param name="content" /> <xsl:param name="tag" /> <xsl:param name="default" /> <xsl:choose> <xsl:when test="$content != ''"> <xsl:element name="{$tag}"> <xsl:value-of select="$content" /> </xsl:element> </xsl:when> <xsl:when test="$default != ''"> <xsl:element name="{$tag}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:when> </xsl:choose> </xsl:template> When you are testing whether a string ($content and $default are both strings) has content or not, you can use the fact that strings are true() if they have content, and false() if they don't. So within a test (which automatically interprets its contents as a boolean expression): $content != '' is equivalent to simply: $content And the template can alternatively be: <xsl:template name="empty-content"> <xsl:param name="content" /> <xsl:param name="tag" /> <xsl:param name="default" /> <xsl:choose> <xsl:when test="$content"> <xsl:element name="{$tag}"> <xsl:value-of select="$content" /> </xsl:element> </xsl:when> <xsl:when test="$default"> <xsl:element name="{$tag}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:when> </xsl:choose> </xsl:template> When you're passing parameters that include things about the content or name of a node, then you may as well change the template to a moded template that matches that node, and work out the content/name within the template. This saves on xsl:with-params, which are very verbose: <xsl:template match="people"> <Star> <FirstName><xsl:value-of select="N1" /></FirstName> <LastName><xsl:value-of select="N2" /></LastName> <xsl:apply-templates select="N3" mode="empty_content"> <xsl:with-param name="tag">MI</xsl:with-param> <xsl:with-param name="default">N/A</xsl:with-param> </xsl:call-template> <xsl:call-template select="Sex" mode="empty_content"> <xsl:with-param name="tag">Gender</xsl:with-param> <xsl:with-param name="default"></xsl:with-param> </xsl:call-template> </Star> </xsl:template> <xsl:template match="*" mode="empty-content"> <xsl:param name="tag" /> <xsl:param name="default" /> <xsl:choose> <xsl:when test="string(.)"> <xsl:element name="{$tag}"> <xsl:value-of select="." /> </xsl:element> </xsl:when> <xsl:when test="not($default)"> <xsl:element name="{$tag}"> <xsl:value-of select="$default" /> </xsl:element> </xsl:when> </xsl:choose> </xsl:template> A final point - if you're worried about the formatting of your output, then I suggest you use: <xsl:output indent="yes" /> near the top of your stylesheet. This will make the XSLT processor indent things sensibly for you. Cheers, Jeni Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: How to delete empty element tag, Guangzu Wang (Housto | Thread | concat of two strings to create an , Mala Ramakrishnan |
Re: Entity Reference Question, Miloslav Nic | Date | RE: Entity Reference Question, Lee Goddard |
Month |