0

Hi i am trying to get the files which have type html. I am getting it fine. but my problem when there are not files with html it shows empty. but i want to display some message like "no htmls were submitted". i would have used counter variable in normal programming languages. here i am unable to do it please help me solve this. thanks

NOTE: xslt 1.0 is needed.

xml:

<?xml version="1.0" encoding="UTF-8"?>
<Files>
   <Path class="com.interwoven.cssdk.filesys.CSAreaRelativePath" path="MS/homedemo.html" type="html" />
   <Path class="com.interwoven.cssdk.filesys.CSAreaRelativePath" path="MS/test125.html" type="html" />
   <Path class="com.interwoven.cssdk.filesys.CSAreaRelativePath" path="iwov-resources/css/akz.css" type="css" />
   <Path class="com.interwoven.cssdk.filesys.CSAreaRelativePath" path="iwov-resources/css/animate.css" type="css" />
   <Path class="com.interwoven.cssdk.filesys.CSAreaRelativePath" path="iwov-resources/css/base.css" type="css" />
   <Path class="com.interwoven.cssdk.filesys.CSAreaRelativePath" path="iwov-resources/css/font-awesome-ie7.css" type="css" />
</Files>

xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <p>
                <xsl:apply-templates select="//Files" />
            </p>
        </html>
    </xsl:template>
    <xsl:template match="//Files">
        <h1 style="background: #979797;border-radius: 5px;color: #FFF;text-shadow: 1px 1px 1px #000;padding: 5px;font-size:16px;">US files are now live and you can access them using the following URLs:</h1>
        <ol>
            <xsl:for-each select="//Files/Path">        
                <xsl:variable name="type">
                    <xsl:choose>
                        <xsl:when test="@type">
                            <xsl:value-of select="@type" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="'html'" />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable> 
                <xsl:variable name="path" select="@path" />

                        <xsl:choose>
                            <xsl:when test="$type='html'">
                                <li>    
                                    <a class="iw-base-link">
                                        <xsl:attribute name="href">
                                            <xsl:value-of select="$path"/>
                                        </xsl:attribute>
                                        <xsl:value-of select="$path" />
                                    </a>
                                </li>
                            </xsl:when>
                        </xsl:choose>
            </xsl:for-each>                         
        </ol>
        </xsl:template>
</xsl:stylesheet>

When we have type html files then show below thing:

US files are now live and you can access them using the following URLs:

1.MS/homedemo.html
2.MS/test125.html

When we don't have type html files then show below thing:

US files are now live and you can access them using the following URLs:

NO html files were submitted.

3 Answers 3

4

Your XSLT is a bit more complicated than it needs to be. Rather than doing an xsl:for-each over each Path then adding a test inside the loop for the type, add the logic to the "select" of the xsl:for-each itself

<xsl:for-each select="Path[@type='html' or not(@type)]">

Note how this is a 'relative' expression, relative to the Files element you are currently positioned on.

This means you don't need the variable declaration of type in the loop, or the xsl:choose. More importantly though, it does mean you can actually make use of a variable to hold the nodes you want to iterate over

 <xsl:variable name="files" select="Path[@type='html' or not(@type)]" />  

Then, you can use an xsl:choose to check whether this has any nodes in or not

    <xsl:choose>
       <xsl:when test="count($files) = 0">
          No files
       </xsl:when>
       <xsl:otherwise>
          <!-- You existing loop here -->
       </xsl:otherwise>
    <xsl:choose>

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <p>
                <xsl:apply-templates select="//Files" />
            </p>
        </html>
    </xsl:template>
    <xsl:template match="//Files">
        <xsl:variable name="files" select="Path[@type='html' or not(@type)]" />
        <xsl:choose>
           <xsl:when test="count($files) = 0">No files</xsl:when>
           <xsl:otherwise>
        <h1 style="background: #979797;border-radius: 5px;color: #FFF;text-shadow: 1px 1px 1px #000;padding: 5px;font-size:16px;">US files are now live and you can access them using the following URLs:</h1>
        <ol>
            <xsl:for-each select="$files">        
                <xsl:variable name="path" select="@path" />
                 <li>    
                     <a class="iw-base-link" name="{$path}">
                         <xsl:value-of select="$path" />
                     </a>
                 </li>
            </xsl:for-each>
        </ol>
        </xsl:otherwise>
        </xsl:choose>
        </xsl:template>
</xsl:stylesheet>

Do also note the use of "Attribute Value Templates" in creating the hyperlink, to make the XSLT even simpler. The curly braces indicate an expression to be evaluated rather than output literally.

Sign up to request clarification or add additional context in comments.

Comments

2

How about something (a lot) simpler?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="HTMLfiles" select="/Files/Path[@type='html']" />

<xsl:template match="/">
<html>
<xsl:choose>
    <xsl:when test="$HTMLfiles">
        <h1 style="background: #979797;border-radius: 5px;color: #FFF;text-shadow: 1px 1px 1px #000;padding: 5px;font-size:16px;">US files are now live and you can access them using the following URLs:</h1>
        <ol>    
            <xsl:apply-templates select="$HTMLfiles" />
        </ol>
        </xsl:when>
    <xsl:otherwise>
        <h1 style="background: #979797;border-radius: 5px;color: #FFF;text-shadow: 1px 1px 1px #000;padding: 5px;font-size:16px;">NO html files were submitted.</h1>
    </xsl:otherwise>
</xsl:choose>
</html>
</xsl:template>

<xsl:template match="Path">
    <li>    
        <a class="iw-base-link">
            <xsl:attribute name="href">
                <xsl:value-of select="@path"/>
            </xsl:attribute>
            <xsl:value-of select="@path" />
        </a>
    </li>
</xsl:template>

</xsl:stylesheet>

Note that your XSLT places a <h1> inside a <p> element; I am not sure that's a good thing.

Comments

1

There is actually a count() function in xpath :

<ol>
    <xsl:choose>
        <xsl:when test="count(//Files/Path) > 0">
            <xsl:for-each select="//Files/Path">        
                ..........
            </xsl:for-each>   
        </xsl:when>
        <xsl:otherwise>
                NO html files were submitted.
        </xsl:otherwise>
    </xsl:choose>
</ol>

So you can just write a when, otherwise case :)

1 Comment

is it xslt 1.0 version

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.