Solved

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

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

MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

Question has a verified solution.

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

Suggested Solutions

Most of the sites are being standardized with W3C Web Standards. W3C provides lot of web standard services to the web. They have the web specification, process and documentation for all the web standards. You can apply HTML, CSS and Accessibility st…
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
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…

830 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