Solved

XSL to replace  <tag/> with <tag></tag>

Posted on 2008-10-25
5
1,150 Views
Last Modified: 2013-11-18
The requirement is that, all the empty tags in the transformed XML:should look like <tag></tag> and not <tag/>
0
Comment
Question by:creditpointe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
5 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 22803093
Forget it, it can't be done in XSLT.

But basically, any application that has a preference, is not a real XML application, it should not make a difference

From the XML point of view <tag/> and <tag></tag> are equivalent,
and the serialisation engine of your XSLT processor can choose one of both options when serialising.
Most choose the short form, it is not documented and even if you would find a processor that does it the way you want, you can't guarantuee that it will not break in the next version

There are a number of non documented things you can try

1. If it is allowed to put something in between the tags, the tags will be broken
This could be a comment, a space or a process instruction
<tag><xsl:comment>*</xsl:comment></tag>
will generate something like this
<tag><!-- * --></tag>
your follow up XML process should ignore that comment and it could have the same effect

2. If it is not allowed to have something in between the tags, use a post process.
I have a customer who built his own XML loader that puts stuff I send him in a database
He has built his own parser and it is crappy, so it doesn't take <tag/>
For him I use this technique
I create <tag><!-- * --></tag>
and in a post process I use regular expressions that simple remove all the <!-- * --> from the document
This works really well

3. There is one obscure technique that helps with some processors. But it is undocumented and I can't guarantuee that it won't break in one of the next versions. Basically you try to throw something in between the two tags that won't get serialised at the end.
This for example works in Xalan (for Java)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:variable name="empty"/>
 <xsl:template match="tag">
     <tag>
         <xsl:value-of select="$empty"/>
     </tag>
 </xsl:template>
</xsl:stylesheet>
I bet you could find similar constructs that would break the tag in Saxon as well... but these are ugly hacks
I used that for a while, but I strongly recommend not to use dirty hacks like this... the will break at some point

So,
first evaluate if you really need this. If there is a real need it would be because the next step in the pipeline is in default.
There should not be a requirement for what you ask with real XML applications
then evaluate whether it is allowed to put a space or a comment in between,
If you can't put a comment or so in between, still do, but remove it with regular expressions in a post process

I hope this helps you

Geert

0
 

Author Comment

by:creditpointe
ID: 22804165
Thanks Gertone for providing so many options.
The first solution is very interesting.
Allow me to ask a few more questions and add something more to my question.

Is there any way which would allow to put an empty space for all the tags (for the complete inbound xml) processed where there is no text? In other words, if the source xml has <tag></tag> (for any tag across the inbound xml) then the output would consist of <tag> "space" </tag>?
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 22804347
That largely depends on your stylesheet,
but you could have a template
<xsl:template match="*[string-length(.) = 0]">
  <xsl:copy>
    <xsl:text> </xsl:text>
  </xsl:copy>
</xsl:template>

and add this predicate to all other templates you have
<xsl:template match="myNotEmptyElement">
which then should become
<xsl:template match="myNotEmptyElement[* or string-length(normalize-space(.)) > 0]">
to make sure the element has content before processing starts
0
 

Expert Comment

by:avsviswanath
ID: 24304063
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
      <xsl:template match="/">
      <xsl:apply-templates select="*"/>
      </xsl:template>

      <xsl:template match="*">
      <xsl:choose>
      <xsl:when test=". != ''">
      <xsl:element name="{name()}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
      </xsl:element>
      </xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
<xsl:comment>empty element</xsl:comment>
</xsl:element>
</xsl:otherwise>
</xsl:choose>

</xsl:template>

</xsl:stylesheet>
use this it will work.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 24308143
@avsviswanath

That does not really do what the original poster asked,
and was suggested as the first option in the first comment

I add this just in case someone finding this answer in the database thinks that something new was added, after an answer was accepted
0

Featured Post

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…
Suggested Courses

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question