F khader
F khader

Reputation: 45

xslt - create empty file using xslt 1.0

I am trying to create an empty file through xslt.

The input sample is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Businessman>
    <siblings>
        <sibling>John </sibling>
    </siblings>
    <child> Pete </child>
    <child> Ken </child>
</Businessman>

When the input contains any presence of 'child' tags, it should produce the file AS IS. When the input does not have any 'child' tag, I need an empty file (0 byte file) created.

This is what I tried:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
 <xsl:template match="@*|node()">
   <xsl:choose>
     <xsl:when test="/Businessman/child">
       <xsl:copy>
         <xsl:apply-templates select="@*|node()" />
       </xsl:copy>
     </xsl:when>
     </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

This gives the file unchanged when there is any 'child' tag present. But did not produce any empty file when there is no 'child' tag.

The file I need to test will look like:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Businessman>
    <siblings>
        <sibling>John </sibling>
    </siblings>
</Businessman>

Any help would be great!

Thanks

Upvotes: 0

Views: 1382

Answers (2)

Filburt
Filburt

Reputation: 18082

Simple enough - Just don't try to do everything in one template, don't forget to omit the xml declaration and get the xpath right:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Businessman[child]" priority="9">
        <xsl:element name="Businessman">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="Businessman"  priority="0" />

    <xsl:template match="@* | node()">

        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

Reputation: 25054

If you want the processor to go to the trouble of opening the output file, you have to give it something to write to the output file. Try an empty text node. And you only need to make the decision 'copy or not?' once.

One way to make the decision just once and produce empty output if the condition is not met would be to replace your template with:

<xsl:template match="/">
  <xsl:choose>
    <xsl:when test="/Businessman/child">
      <xsl:copy-of select="*"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

This works as expected with xsltproc. (If you find yourself getting a file containing an XML declaration and nothing else, try adjusting the parameters on xsl:output.)

But when I have found myself with a similar situation (perform this transform if condition C holds, otherwise ...), I have simply added a template for the document node that would look something like this for your case:

<xsl:choose>
  <xsl:when test="/Businessman/child">
    <xsl:apply-templates/>
  </
  <xsl:otherwise>
    <xsl:message terminate="yes">No children in this input, dying ...</
  </
</

That way I get no output at all rather than zero-length output.

Upvotes: 1

Related Questions