Solved

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

Posted on 2008-10-25
5
1,143 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
  • 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Preface This article introduces an authentication and authorization system for a website.  It is understood by the author and the project contributors that there is no such thing as a "one size fits all" system.  That being said, there is a certa…
Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will learn how to count occurrences of each item in an array.

863 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now