Get file size from media folder in Umbraco using XSLT - xslt

Below is a part of my Umbraco xslt where I am outputting a PDF file link and the size of the file. The problem I am having, is targetting the size attribute of the media file. The size attribute has the alias of umbracoBytes.
I just seem to not be able to target this.
So all I am outputting at the moment is the link to open the PDF, but not the file size.
Anyone who can help would be greatly appreciated. Thanks.
<td>
<xsl:if test="document= ''">
<xsl:value-of select="#nodeName"/>
</xsl:if>
<xsl:if test="document != ''">
<a target="_blank">
<xsl:attribute name="href">
<xsl:value-of select="umbraco.library:GetMedia(document, 'false')/umbracoFile"/>
</xsl:attribute>
<xsl:value-of select="#nodeName"/>
<xsl:variable name="size" select="data [#alias = 'umbracoBytes']" />
<xsl:variable name="sizeAndSuffix">
<xsl:choose>
<xsl:when test="$size >= 1073741824">
<xsl:value-of select="format-number($size div 1073741824,'#,###')"/>
<xsl:text>GB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1048576">
<xsl:value-of select="format-number($size div 1048576,'#,###')"/>
<xsl:text>MB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1024">
<xsl:value-of select="format-number($size div 1024,'#,###')"/>
<xsl:text>KB</xsl:text>
</xsl:when>
<xsl:when test="$size > 0 and $size < 1024">
<xsl:value-of select="format-number($size div 0,'#,###')"/>
<xsl:text>Bytes</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>0 Bytes</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
</a>
</xsl:if>
</td>

The problem (I think) is that because you didn't prepend your $size variable select attribute with any target, so by default it uses $currentPage or the current value in a loop iteration.
Try assigning the GetMedia statement to a variable and then get the data from that. Your code appears to have syntax used in different versions of Umbraco, so I can't quite tell which one you're using. Different versions of Umbraco use different underlying XML structure.
If using < Umbraco 4.5.1
<xsl:variable name="myDocument" select="umbraco.library:GetMedia(document, 'false')" />
<a target="_blank">
<xsl:attribute name="href">
<xsl:value-of select="$myDocument/data[#alias='umbracoFile']"/>
</xsl:attribute>
...
<xsl:variable name="size" select="$myDocument/data [#alias = 'umbracoBytes']" />
...
</a>
If using >= Umbraco 4.5.1
<xsl:variable name="myDocument" select="umbraco.library:GetMedia(document, 'false')" />
<a target="_blank">
<xsl:attribute name="href">
<xsl:value-of select="$myDocument/umbracoFile"/>
</xsl:attribute>
...
<xsl:variable name="size" select="$myDocument/umbracoBytes" />
...
</a>

I managed to work it out.
I removed the wrapping variable and created a variable named size which selects the alias UmbracoBytes (the file size)
I then pass the variable through the choose function and this outputs the correct size extension.
Thanks for all your suggestions I really appreciate that!
<xsl:variable name="size" select="umbraco.library:GetMedia(document, 'false')/umbracoBytes"/>
<xsl:choose>
<xsl:when test="$size >= 1073741824">
<xsl:value-of select="format-number($size div 1073741824,'#,###')"/>
<xsl:text>GB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1048576">
<xsl:value-of select="format-number($size div 1048576,'#,###')"/>
<xsl:text>MB</xsl:text>
</xsl:when>
<xsl:when test="$size >= 1024">
<xsl:value-of select="format-number($size div 1024,'#,###')"/>
<xsl:text>KB</xsl:text>
</xsl:when>
<xsl:when test="$size > 0 and $size < 1024">
<xsl:value-of select="format-number($size div 0,'#,###')"/>
<xsl:text>Bytes</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>0 Bytes</xsl:text>
</xsl:otherwise>
</xsl:choose>

Related

xsl:choose - Hardcoded 0's being added to end of XSLT string

I am having an issue that I cannot figure out in XLST where there are hardcoded 0's being added to the end of a string that I am not calling for. I am using a choose element to prompt placement of the string or to otherwise pick three 0's.
Can anyone tell in my code what I am doing wrong? See below:
<xsl:for-each select="Export/Record">
<xsl:if test="DebitAmount!=0 and DebitAmount!=''">
<xsl:value-of select="ChargedCorpLedgerCode" /><xsl:text>,</xsl:text>
<xsl:value-of select="DepartmentLedgerCode" /><xsl:text>,</xsl:text>
<xsl:value-of select="CategoryJournalNumber" /><xsl:text>,</xsl:text>
<xsl:value-of select="PFAM" /><xsl:text> 0000,</xsl:text>
<xsl:value-of select="LOC" /><xsl:text> 0000,</xsl:text>
<xsl:value-of select="ACTV" /><xsl:text> 0000,</xsl:text>
<xsl:value-of select="CLIENT"/><xsl:text> 0000000,</xsl:text>
<xsl:choose>
<xsl:when test="ProjectLedgerCode=null">
<xsl:value-of select="ProjectLedgerCode" /><xsl:text>,</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="ProjectLedgerCode" /><xsl:text> 000,</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="DebitAmount" /><xsl:text>,</xsl:text>
<xsl:value-of select="''" /><xsl:text>,</xsl:text>
<xsl:value-of select="CategoryDesc" /><xsl:text>,</xsl:text>
<xsl:text>
</xsl:text>
</xsl:if>
my outcome looks like the below where the 000's are adding correctly when the column is blank, but when it is not, it adds the ProjectLedgerCode + 000
This test:
<xsl:when test="ProjectLedgerCode=null">
will return true if the string-value of ProjectLedgerCode is equal to the string-value of a sibling element named null.
If you want to test for ProjectLedgerCode not having a string-value, use:
<xsl:when test="ProjectLedgerCode=''">
or:
<xsl:when test="not(string(ProjectLedgerCode))">
In addition, I believe your results are mixed up.

XSL word citation change

I have found a *.xsl citation template for Word 2010. It is almost what I need I just need a few changes done.
First it shows in the output e.g. [Str17] but it should show [STR-17]
Further it shows the bibliography not in a table with a tab in between the TAG and the entry.
e.g.
looks like that
but i need
I need that format
I just can't adjust the xsl to my needs. I have been trying for a while now and trying to find any other xsl file but no luck. This kind to citation is pretty common in engineering so I am sure I am not the only one looking for a solution.
I think for the first part of my question regarding the style of the Tag the relevant code is:
<xsl:if test="msxsl:node-set($ListPopulatedWithMain)/b:Citation/b:FirstAuthor">
<!-- hier wird die Klammer [ angezeigt -->
<xsl:call-template name="templ_prop_ISO690_GeneralOpen"/>
</xsl:if>
<xsl:if test="msxsl:node-set($ListPopulatedWithMain)/b:Citation/b:PagePrefix">
<xsl:value-of select="/b:Citation/b:PagePrefix"/>
</xsl:if>
<!-- <xsl:value-of select="$displayAuthor" /> nicht den Author anzeigen sondern den Tag-->
<xsl:value-of select="msxsl:node-set($ListPopulatedWithMain)/b:Citation/b:Source/b:Tag" />
<xsl:if test="string-length($displayTitle) > 0">
<xsl:if test="string-length($displayAuthor) > 0">
<xsl:call-template name="templ_prop_ListSeparator"/>
</xsl:if>
<xsl:value-of select="$displayTitle"/>
</xsl:if>
<xsl:if test="string-length($year) > 0">
<xsl:if test="string-length($displayTitle) > 0">
<xsl:call-template name="templ_prop_ListSeparator"/>
</xsl:if>
<!-- <xsl:value-of select="$year"/> nicht das Jahr anzeigen lassen -->
</xsl:if>
<xsl:if test="string-length($author0) = 0 and string-length($title0) = 0 and string-length($year0) = 0">
<xsl:value-of select="msxsl:node-set($ListPopulatedWithMain)/b:Citation/b:Source/b:Tag"/>
</xsl:if>
<xsl:if test="string-length($volume) > 0 or string-length($pages) > 0">
<xsl:if test="string-length($displayAuthor) > 0 or string-length($displayTitle) > 0 or string-length($year) > 0">
<xsl:call-template name="templ_prop_Space"/>
</xsl:if>
<xsl:choose>
<xsl:when test="string-length($volume) > 0 and string-length($pages) > 0">
<xsl:value-of select="$volume"/>
<xsl:call-template name="templ_prop_Enum"/>
<xsl:value-of select="$pages"/>
</xsl:when>
<xsl:when test="string-length($volVolume) > 0">
<xsl:value-of select="$volVolume"/>
</xsl:when>
<xsl:when test="string-length($ppPages) > 0">
<xsl:value-of select="$ppPages"/>
</xsl:when>
</xsl:choose>
</xsl:if>
<xsl:if test="/b:Citation/b:PageSuffix">
<xsl:value-of select="/b:Citation/b:PageSuffix"/>
</xsl:if>
<xsl:if test="/b:Citation/b:LastAuthor">
<!-- hier wird die Klammer ] angezeigt -->
<xsl:call-template name="templ_prop_ISO690_GeneralClose"/>
</xsl:if>
<xsl:if test="not(/b:Citation/b:LastAuthor)">
<xsl:call-template name="templ_prop_GroupSeparator"/>
</xsl:if>
I have tried to add - in this part but it just shows the hyphen at the beginning or at the end. Changing the letters into uppercase is still magic for me. could not find the relevant section.
For the 2nd part I will upload the file since it is pretty long and i don't want to post the entire code. Can't do it from work since every possibility for an upload is blocked by my company.
At first I would recommend you to use templates e.g:
<xsl:template name="Citation">
<xsl:apply-templates/>
</xsl:template>
<xsl:template name="FirstAuthor">
<xsl:call-template name="templ_prop_ISO690_GeneralOpen"/>
</xsl:template>
<xsl:template name="PagePrefix">
<xsl:value-of select="."/>
</xsl:template>
...
This is not necessary, but better code style.
Your code is unreadable for me so I will answer your question like that:
- For transforming the text to upper-case use
<xsl:value-of select="upper-case(//some-xpath)"/>
To insert tables use code like this:
Text
Text
If you expect a better answer please post some readable code

Check if at least one child has a specific value with xslt 1.0

This is my XML:
<LIGHT_INFORMATION_LIST>
<LIGHT_INFORMATION>
<LIGHT_CHARACTERISTICS>Al</LIGHT_CHARACTERISTICS>
<LIGHT_COLOUR>W-G</LIGHT_COLOUR>
</LIGHT_INFORMATION>
<LIGHT_INFORMATION>
<LIGHT_CHARACTERISTICS>Al</LIGHT_CHARACTERISTICS>
<LIGHT_COLOUR>W-R</LIGHT_COLOUR>
</LIGHT_INFORMATION>
<LIGHT_INFORMATION>
<LIGHT_CHARACTERISTICS>F</LIGHT_CHARACTERISTICS>
<LIGHT_COLOUR>R</LIGHT_COLOUR>
</LIGHT_INFORMATION>
<LIGHT_INFORMATION>
<LIGHT_CHARACTERISTICS>F</LIGHT_CHARACTERISTICS>
<LIGHT_COLOUR>G</LIGHT_COLOUR>
</LIGHT_INFORMATION>
<LIGHT_INFORMATION>
<LIGHT_CHARACTERISTICS>F</LIGHT_CHARACTERISTICS>
<LIGHT_COLOUR>W</LIGHT_COLOUR>
</LIGHT_INFORMATION>
</LIGHT_INFORMATION_LIST>
I woul insert a control:
if at least one element of LIGHT_COLOUR into this LIGHT_INFORMATION_LIST contain '-'
I tried whit this, but is completely wrong:
<xsl:choose>
<xsl:when test="not(contains(.,'-'))">
<!-- do A -->
</xsl:when>
<xsl:otherwise>
<!-- do B -->
</xsl:otherwise>
</xsl:choose>
This is actually my XSLT code:
<xsl:for-each select="LIGHT_INFORMATION">
<xsl:for-each select="LIGHT_COLOUR">
<xsl:choose>
<xsl:when test="not(contains(.,'-'))"> <!-- This is the test Required -->
<xsl:choose>
<xsl:when test="following-sibling::LIGHT_RANGE >= 15">
<span style="font-family:Univers Condensed; font-weight:bold;">
<xsl:if test="not(preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF])">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test=". != preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF]">
<xsl:value-of select="."/>
</xsl:if>
</span>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not(preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF])">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test=". != preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF]">
<xsl:value-of select="."/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
ciao <!-- I would insert this control here if LIGHT_COLOUR contain '-' -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
Now the output is:
ciao ciao R G W
I would, if only one element in this node of LIGHT_INFORMATION_LIST contains into LIGHT_COLOUR '-' write 'Ciao'
Thi is the solution:
<xsl:for-each select="LIGHT_INFORMATION">
<xsl:choose>
<xsl:when test="not(contains(parent::LIGHT_INFORMATION_LIST//LIGHT_COLOUR, '-'))"> <!-- This is the solution -->
<xsl:for-each select="LIGHT_COLOUR">
<xsl:choose>
<xsl:when test="following-sibling::LIGHT_RANGE >= 15">
<span style="font-family:Univers Condensed; font-weight:bold;">
<xsl:if test="not(preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF])">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test=". != preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF]">
<xsl:value-of select="."/>
</xsl:if>
</span>
</xsl:when>
<xsl:otherwise>
<xsl:if test="not(preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF])">
<xsl:value-of select="."/>
</xsl:if>
<xsl:if test=". != preceding::LIGHT_COLOUR[1][preceding::IMMUTABLE_ID = $EF]">
<xsl:value-of select="."/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
Ciao
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
Insert the control at the head and using PARENT.
following-sibling would only find a LIGHT_COLOR if it were on the same level (ie the current node was a LIGHT_CHARACTERISTIC node and even then it would only ever find one.
To look at all of them, you need to specify a path that includes them all, either globally or relative to the current node. In this case:
/LIGHT_INFORMATION_LIST/LIGHT_INFORMATION/LIGHT_COLOUR
This path will select all LIGHT_COLOR nodes. Now we want to filter out each node if it does not contain a "-":
/LIGHT_INFORMATION_LIST/LIGHT_INFORMATION/LIGHT_COLOUR[contains(., "-")]
We aren't actually interested in any of the individual nodes, we just want to know how many there are so:
count (/LIGHT_INFORMATION_LIST/LIGHT_INFORMATION/LIGHT_COLOUR[contains(., "-")])
Therefore, your check would be:
<xsl:when test='count (/LIGHT_INFORMATION_LIST/LIGHT_INFORMATION/LIGHT_COLOUR[contains(., "-")])'>
* Edit: Revised answer to revised question *
If you want one control, then you only want to do it once so move it outside of the loop:
<!-- Do this where we can see all of the LIGHT_COLOR tags -->
<xsl:if test="contains(LIGHT_INFORMATION/LIGHT_COLOR, '-')">
Ciao
</xsl:if>
<xsl:for-each select="LIGHT_INFORMATION">
<!-- as per your existing code. Remove the "otherwise" clause that is creating multiple controls. -->

XSLT setting a variable to either foo or #foo depending on presence of attribute

I'm trying to set parttext to #head if use_head="true" is not present and to the contents of <head> </head> if use_head="true" is present
<xsl:template match="toc_part">
<xsl:variable name="artnum">
<xsl:value-of select="../#num" />
</xsl:variable>
<xsl:variable name="partnum">
<xsl:value-of select="#num" />
</xsl:variable>
<xsl:variable name="parttext">
<xsl:if test="#use_head">
<xsl:value-of select="head"/>
</xsl:if>
<xsl:if test="not[#use_head]">
<xsl:value-of select="#head"/>
</xsl:if>
</xsl:variable>
<tr>
<td>
 
</td>
<td>
<a class="int" href="{$GBLfilePre}{$artnum}.html#{$artnum}{$partnum}"><xsl:text>Part </xsl:text><xsl:value-of select="$partnum" /></a>
</td>
<td>
<xsl:value-of select="$parttext" />
</td>
</tr>
</xsl:template>
I've also tried:
<xsl:if test="#use_head"><xsl:variable name="parttext"><xsl:value-of select="head"></xsl:variable>
<xsl:if test="not[#use_head"]><xsl:variable name="parttext"><xsl:value-of select="#head"></xsl:variable>
which give parttext undefined when referenced.
Try:
<xsl:variable name="parttext">
<xsl:choose>
<xsl:when test="#use_head='true'">
<xsl:value-of select="head"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#head"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Your current test in the first if statement will evaluate to true() if the #use_head attribute exists, regardless of it's value. If you want the test to evaluate whether or not it's value is equal to "true" you should use test="#use_head='true'".
The second if statement is evaluating whether or not there is an element named "not" that has an attribute called "use_head", because the square brackets are a predicate. I believe you had intended to use the not() function: not(#use_head='true')
You could then use an <xsl:choose> instead of two if blocks:
<xsl:variable name="parttext">
<xsl:choose>
<xsl:when test="#use_head='true'">
<xsl:value-of select="head"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#head"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
In XSLT 2.0:
<xsl:variable name="head"
select="if (#use_head='true') then head else #head"/>
In XSLT 1.0, either Hansen's solution, or
<xsl:variable name="head"
select="head[current()/#use_head='true'] |
#head[not(current()/#use_head='true')]"/>
In future, please tell us which version of XSLT you are using. One can sort of guess this must be XSLT 1.0 because in 2.0 the solution is trivial, but it's better not to have to guess.

Using Multiple Nested Attributes in XSLT

What is the best way to construct nested attributes in XSL?
My issue is that onmouseover is an attribute and the src of img is an attribute. The current error given by the builder is:
An item of type 'Element' cannot be constructed within a node of type 'Attribute'.
I used to have an issue of multiple attributes which would have been my preferred route but throws an error:
Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added.
I have since attempted the following as a workaround but with no luck
<xsl:template name="Item3">
<xsl:param name="ItemID" />
<xsl:variable name="IMGSRC">
<xsl:choose>
<xsl:when test="$ItemID = 'ST-18/NM/NM/36'">
<xsl:value-of select="concat('imagesCategories/','ST-18-NM-NM-36','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/NM/NM/48'">
<xsl:value-of select="concat('imagesCategories/','ST-18-NM-NM-48','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/NM/NM/72'">
<xsl:value-of select="concat('imagesCategories/','ST-18-NM-NM-72','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/SMAM/SMAM/12'">
<xsl:value-of select="concat('imagesCategories/','ST18-SMAM-SMAM-12','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/SMAM/SMAM/24'">
<xsl:value-of select="concat('imagesCategories/','ST18-SMAM-SMAM-24','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/SMAM/SMAM/36'">
<xsl:value-of select="concat('imagesCategories/','ST18-SMAM-SMAM-36','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/SMAM/SMAM/48'">
<xsl:value-of select="concat('imagesCategories/','ST18-SMAM-SMAM-48','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/SMAM/SMAM/60'">
<xsl:value-of select="concat('imagesCategories/','ST18-SMAM-SMAM-60','.jpg')"/>
</xsl:when>
<xsl:when test="$ItemID = 'ST-18/SMAM/SMAM/72'">
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('imagesCategories/',$ItemID,'.jpg')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="Items/Item[#ItemID=$ItemID]">
<xsl:attribute name="onmouseover">
<xsl:text>ddrivetip('</xsl:text>
<img src="{$IMGSRC}"/>
<br />
<b>
<xsl:value-of select="Items/Item[#ItemID=$ItemID]/#ItemID" />
</b>
<br />
<b>
<xsl:value-of select="Items/Item[#ItemID=$ItemID]/#ItemDescription" />
</b>
<br />
<br />
<xsl:text>Price (01-09): </xsl:text>
<xsl:value-of select="Items/Item[#ItemID=$ItemID]/#PriceLevel1" />
<br/>
<xsl:text>Price (10-24): </xsl:text>
<xsl:value-of select="Items/Item[#ItemID=$ItemID]/#PriceLevel2" />
<br/>
<xsl:text>Price (25-49): </xsl:text>
<xsl:value-of select="Items/Item[#ItemID=$ItemID]/#PriceLevel3" />
<br/>
<xsl:text>Qty In Stock: </xsl:text>
<xsl:value-of select="Items/Item[#ItemID=$ItemID]/#QtyOnHand" />
<br />
<br />
<xsl:text>Click </xsl:text>
<b>
<xsl:text>"BUY!"</xsl:text>
</b>
<xsl:text> to add this item to your shopping cart</xsl:text>
<xsl:text>', '', '300')</xsl:text>
</xsl:attribute>
There is some additional code and then the proper closing tags.
Thanks everyone!
It looks like you are trying to pass html as a string to your ddrivetip function. However, you are adding these as nodes instead of text, and nodes cannot be added added to attributes, so one solution is to make the nodes text (You'll have to escape the brackets and double quotes too).
However, you are putting a lot of information into the onmouseover event, which is not recommended. Instead of what you are currently doing, I would make a hidden element with an id that incorporates your itemId with the contents of your html and then show that as needed in your onmouseover event.
Use CDATA sections so that the XSLT Processor interpret your img tags as a part of text nodes and not as an attempt to insert element nodes into an attribute (it is forbidden by the XML specification)
<xsl:attribute name="onmouseover">
<xsl:text><![CDATA[ddrivetip('<img src="]]></xsl:text>
<xsl:value-of select="$IMGSRC" />
<xsl:text><![CDATA["/>
<br />
...