Umbraco - Getting Textstring value - xslt

I'm trying to get the value of a text string of page, assign a url to it, and then display the result on a different page using xslt. I'm not sure how to get the value of the textstring.
Here is my macro:
<!-- Input the related links property alias here -->
<xsl:variable name="fieldName" select="/macro/fieldName"/>
<xsl:template match="/">
<xsl:if test="$fieldName != ''">
<!-- The fun starts here -->
<xsl:element name="a">
<xsl:if test="./new-window[. = 'True']">
<xsl:attribute name="target">_blank</xsl:attribute>
</xsl:if>
<xsl:attribute name="href">
<xsl:value-of select="/myUrl.aspx"/>
</xsl:attribute>
<xsl:value-of select="./#title"/>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Found it! select="$parent/*[name() = $fieldName]

Related

Umbraco current member details comma separated multiple textstrings list

I'm creating a macro that sources a property from the current member. The property uses the "multiple textstrings" datatype, and each textstring contains a media ID, the version number and the date and time added.
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:template match="/">
<xsl:if test="count(umbraco.library:GetCurrentMember()/assetDownloads/values/value) > 0">
<ul>
<xsl:for-each select="umbraco.library:GetCurrentMember()/assetDownloads/values/value">
<li>
<xsl:if test="./preview != ''">
<img>
<xsl:attribute name="src">
<xsl:value-of select="./preview" />
</xsl:attribute>
</img>
</xsl:if>
<p><xsl:value-of select="current()"/></p>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
This results in the following:
1475,1,28-Dec-12 01:26:45
1475,1,28-Dec-12 01:27:03
The first values are the media types ID, the second value is its version number and the third value is the date and time it was downloaded.
This is how to display the first value as the preview image and the nodeName:
<!-- First value as preview image and nodeName -->
<xsl:if test="position() = 1">
<img>
<xsl:attribute name="src">
<xsl:value-of select="umbraco.library:GetMedia(., 0)/preview" />
</xsl:attribute>
</img>
<p><xsl:value-of select="umbraco.library:GetMedia(., 0)/#nodeName" /></p>
</xsl:if>
How can I seperate the string so I can display details from the media type? I'd like to display the preview image from media type and the nodeName of the media type.
Try using Umbraco split function separated via , (Comma) as following
<xsl:variable name="contentSplit" select="umbraco.library:Split(current(), ',')" />
Refactored code:
<xsl:if test="count(umbraco.library:GetCurrentMember()/assetDownloads/values/value) > 0">
<ul>
<xsl:for-each select="umbraco.library:GetCurrentMember()/assetDownloads/values/value">
<li>
<xsl:if test="./preview != ''">
<img>
<xsl:attribute name="src">
<xsl:value-of select="./preview" />
</xsl:attribute>
</img>
</xsl:if>
<p>
<!-- Split values via , comma using below function -->
<xsl:variable name="contentSplit" select="umbraco.library:Split(current(), ',')" />
<xsl:for-each select="$contentSplit/value">
<!-- First value as media type id -->
<xsl:if test="position() = 1">
Media Type Id: <xsl:value-of select="." />
</xsl:if>
<!-- Second value as version number -->
<xsl:if test="position() = 2">
Version: <xsl:value-of select="." />
</xsl:if>
<!-- Third value as date and time of download -->
<xsl:if test="position() = 3">
Date Time: <xsl:value-of select="." />
</xsl:if>
</xsl:for-each>
</p>
</li>
</xsl:for-each>
</ul>
</xsl:if>
Let me know if you need more explanation, Thanks

XSLT 1.0 select value-of in node set with string

I have some trouble with selecting values in node set. I have a string variable,
which concatenate in path of next existed node in xml. But when i try to select valu from it,
it results in paste of value of this variable, not the value of node. I can`t find how i can
convert string to node set for proper selection. Please, help.
<xsl:for-each select="result/node()">
<xsl:copy>
<xsl:for-each select="./node()">
<xsl:copy>
<xsl:attribute name="rating">
<xsl:text>0</xsl:text>
</xsl:attribute>
<xsl:choose>
<xsl:when test="translate(
substring(.,1,3),
$upCase,
$lowCase
) = 'id_'">
<xsl:value-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="cval"
select="concat(
'/survey/checkbox_value/',
local-name(),
'/.'
)" />
<xsl:value-of select="$cval" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
You don't need to convert anything. It could be done with plain xpath.
<xsl:variable name="local_name" select="local-name()"/>
<xsl:value-of select="/survey/checkbox_value/node()[
local-name() = $local_name
]"/>

How do I use XSLT to put a node set into an attribute value?

I have an xsl template that I want to call to put into an HTML node attribute:
<xsl:variable name="onClickJavaScript">
<xsl:call-template name="GetOnClickJavaScript" />
</xsl:variable>
<a id="123">
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
</a>
My problem is that the call-template returns a node set and the attribute value wants to be a string. I can't seem to find any way to transform the node set into a string that works.
I have tried changing the value-of line to:
<xsl:value-of select="$onClickJavaScript/text()" />
But it complains that it needs to return a node set and that does not (which is what I was hoping, without the complaining part).
In the Visual Studio debugger I can see that $onClickJavaScript is a NodeSet with a single dimension and item. My string is buried in there, but not accessible :-(.
UPDATE...
When I call my template, it goes through a big case statement and calls another template. This other template has a <xsl:choose> and it goes down the following path in this case:
<xsl:when test="$isPrimary='true'">
<!-- Just provide the onclick event JavaScript -->
<xsl:value-of select='concat($launchMethod, "(this, &apos;", $id, "&apos;, &apos;", $nodeid, "&apos;, &apos;", $instanceid, "&apos;)")' />
</xsl:when>
With the information provided, your first sample should work, i.e.
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
should insert an onclick attribute with the (string) value of $onClickJavaScript.
You can even simplify your XSLT by using an attribute value template:
<a id="123" onclick="{$onClickJavaScript}">...</a>
Or get rid of the variable and call the template inside the attribute node:
<xsl:attribute name="onclick">
<xsl:call-template name="GetOnClickJavaScript" />
</xsl:attribute>
My problem is that the call-template
returns a node set and the attribute
value wants to be a string. I can't
seem to find any way to transform the
node set into a string that works.
The problem is in the code you haven't shown.
In fact, I cannot reproduce this problem at all.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="onClickJavaScript">
<xsl:call-template name="GetOnClickJavaScript" />
</xsl:variable>
<xsl:variable name="onClickJavaScript2">
<xsl:call-template name="GetOnClickJavaScript2" />
</xsl:variable>
<a id="123">
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
</a>
<a id="123456">
<xsl:attribute name="onclick">
<xsl:value-of select="$onClickJavaScript" />
</xsl:attribute>
</a>
</xsl:template>
<xsl:template name="GetOnClickJavaScript">Hello</xsl:template>
<xsl:template name="GetOnClickJavaScript2">
<a>Hello</a>
</xsl:template>
</xsl:stylesheet>
when applied on any XML document (not used) produces its output without any errors:
<a id="123" onclick="Hello"/>
<a id="123456" onclick="Hello"/>
I'm not able to reproduce this either... here's what I tried, the onclick on the a gets "foo(this, '3', 'test')". What else is different? What is the result-tree-fragment that you're trying to call xsl:value-of on?
<xsl:template match="/">
<xsl:variable name="onclick-val">
<xsl:call-template name="foo" />
</xsl:variable>
<a>
<xsl:attribute name="onclick">
<xsl:value-of select="$onclick-val" />
</xsl:attribute>
</a>
</xsl:template>
<xsl:template name="foo">
<xsl:choose>
<xsl:when test="false()">
false
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="callme" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="callme">
<xsl:choose>
<xsl:when test="true()">
<xsl:value-of select='concat("foo", "(this, &apos;", "3", "&apos;, &apos;", "test", "&apos;)")' />
</xsl:when>
<xsl:otherwise>
false
</xsl:otherwise>
</xsl:choose>
</xsl:template>

XSLT blank xmlns="" after transform

I'm using an XSLT to transform from one XML standard to another. The particular resulting XML standard contains a root element which is part of a namespace and a child node which is part of another namepsace.
The transform successfully reflects these namespaces but the child's child now contains a blank xmlns attribute. How can I prevent this xmlns=""?
XSLT Snippet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#* | node()">
<xsl:apply-templates select="REQUEST_GROUP" />
</xsl:template>
<xsl:template match="REQUEST_GROUP">
<ONCORE_ERECORD xmlns="http://test.com">
<xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/>
<PAYMENT PaymentType="ACH" />
<TRANSACTION_INFO _AgentKey="" _AgentPassword="" />
</ONCORE_ERECORD>
</xsl:template>
<xsl:template match="PACKAGE">
<DOCUMENT_RECORDATION xmlns="http://test2.org">
<xsl:apply-templates select="PRIA_DOCUMENT"/>
</DOCUMENT_RECORDATION>
</xsl:template>
<xsl:template match="PRIA_DOCUMENT">
<PRIA_DOCUMENT _PRIAVersion="1.2">
<xsl:attribute name="_Type">
<xsl:value-of select="#RecordableDocumentType"/>
</xsl:attribute>
<xsl:attribute name="_Code"/>
<xsl:apply-templates select="GRANTOR" />
<xsl:apply-templates select="GRANTEE" />
<xsl:choose>
<xsl:when test="count(PROPERTY) = 0">
<PROPERTY>
<xsl:attribute name="_StreetAddress">
<xsl:value-of select="#StreetAddress"/>
</xsl:attribute>
<xsl:attribute name="_StreetAddress2">
<xsl:value-of select="#StreetAddress2"/>
</xsl:attribute>
<xsl:attribute name="_City">
<xsl:value-of select="#City"/>
</xsl:attribute>
<xsl:attribute name="_State">
<xsl:value-of select="#State"/>
</xsl:attribute>
<xsl:attribute name="_PostalCode">
<xsl:value-of select="#PostalCode"/>
</xsl:attribute>
<xsl:attribute name="_County">
<xsl:value-of select="#County"/>
</xsl:attribute>
<xsl:apply-templates select="LEGAL_DESCRIPTION"/>
</PROPERTY>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="PROPERTY" />
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="count(PARTIES) = 0">
<PARTIES>
<_RETURN_TO_PARTY _UnparsedName="" _StreetAddress="" _StreetAddress2="" _City="" _State="" _PostalCode="" />
</PARTIES>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="PARTIES" />
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="EXECUTION" />
<xsl:apply-templates select="CONSIDERATION" />
<xsl:apply-templates select="RECORDABLE_DOCUMENT/_ASSOCIATED_DOCUMENT" />
<xsl:apply-templates select="EMBEDDED_FILE" />
</PRIA_DOCUMENT>
Source XML:
<REQUEST_GROUP PRIAVersionIdentifier="2.4">
<REQUEST>
<PRIA_REQUEST _Type="RecordDocuments">
<PACKAGE>
<PRIA_DOCUMENT PRIAVersionIdentifier="2.4" RecordableDocumentSequenceIdentifier="1" RecordableDocumentType="Mortgage">
Resulting XML:
<?xml version="1.0" encoding="utf-8"?>
<ONCORE_ERECORD xmlns="http://test.com">
<DOCUMENT_RECORDATION xmlns="http://test2.org">
<PRIA_DOCUMENT _PRIAVersion="1.2" _Type="Mortgage" _Code="" xmlns="">
This is happening because PRIA_DOCUMENT is in the default namespace, while its parent DOCUMENT_RECORDATION is in a non-default namespace. You must put the PRIA_DOCUMENT in the same namespace as its parent, otherwise the serializer is required to generate xmlns="".
.
.
<xsl:template match="PRIA_DOCUMENT">
<PRIA_DOCUMENT _PRIAVersion="1.2" xmlns="http://pria.org">
.
.
.
See Michael Kay's "XSLT 2.0 and XPATH 2.0, 4th edition", page 475 where he discusses this exact situation.
I found a solution that worked, though it may not have been the most efficient way to achieve the desired results.
I simply changed all literal element declarations to:
</xsl:element>
and declared the namespace. The resulting xslt is as follows:
<xsl:template match="REQUEST_GROUP">
<xsl:element name="ONCORE_ERECORD" namespace="http://test.com">
<xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/>
<xsl:element name="PAYMENT" namespace="http://test.com">
<xsl:attribute name="PaymentType">
<xsl:value-of select="'ACH'"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="TRANSACTION_INFO" namespace="http://test.com">
<xsl:attribute name="_AgentKey">
<xsl:value-of select="''"/>
</xsl:attribute>
<xsl:attribute name="_AgentPassword">
<xsl:value-of select="''"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="PACKAGE">
<xsl:element name="DOCUMENT_RECORDATION" namespace="http://test2.org">
<xsl:apply-templates select="PRIA_DOCUMENT"/>
</xsl:element>
</xsl:template>
<xsl:template match="PRIA_DOCUMENT">
<xsl:element name="PRIA_DOCUMENT" namespace="http://test2.org">
<xsl:attribute name="_PRIAVersion">
<xsl:value-of select="'1.2'"/>
</xsl:attribute>
<xsl:attribute name="_Type">
<xsl:value-of select="#RecordableDocumentType"/>
</xsl:attribute>
<xsl:attribute name="_Code"/>
<xsl:apply-templates select="GRANTOR" />
<xsl:apply-templates select="GRANTEE" />
<xsl:choose>
<xsl:when test="count(PROPERTY) = 0">
<xsl:element name="PROPERTY" namespace="http://test2.org">
<xsl:attribute name="_StreetAddress">
<xsl:value-of select="#StreetAddress"/>
</xsl:attribute>
<xsl:attribute name="_StreetAddress2">
<xsl:value-of select="#StreetAddress2"/>
</xsl:attribute>
<xsl:attribute name="_City">
<xsl:value-of select="#City"/>
</xsl:attribute>
<xsl:attribute name="_State">
<xsl:value-of select="#State"/>
</xsl:attribute>
<xsl:attribute name="_PostalCode">
<xsl:value-of select="#PostalCode"/>
</xsl:attribute>
<xsl:attribute name="_County">
<xsl:value-of select="#County"/>
</xsl:attribute>
<xsl:apply-templates select="LEGAL_DESCRIPTION"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="PROPERTY" />
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="count(PARTIES) = 0">
<xsl:element name="PARTIES" namespace="http://test2.org">
<xsl:element name="_RETURN_TO_PARTY" namespace="http://test2.org">
<xsl:attribute name="_UnparseName">
<xsl:value-of select="''"/>
</xsl:attribute>
<xsl:attribute name="_StreetAddress">
<xsl:value-of select="''"/>
</xsl:attribute>
<xsl:attribute name="_StreetAddress2">
<xsl:value-of select="''"/>
</xsl:attribute>
<xsl:attribute name="_City">
<xsl:value-of select="''"/>
</xsl:attribute>
<xsl:attribute name="_State">
<xsl:value-of select="''"/>
</xsl:attribute>
<xsl:attribute name="_PostalCode">
<xsl:value-of select="''"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="PARTIES" />
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="EXECUTION" />
<xsl:apply-templates select="CONSIDERATION" />
<xsl:apply-templates select="RECORDABLE_DOCUMENT/_ASSOCIATED_DOCUMENT" />
<xsl:apply-templates select="EMBEDDED_FILE" />
</xsl:element>
</xsl:template>
I was having a similar issue even declaring the namespace on the child elements but was still ending up with
xmlns=""
I thought it was due to the xslt transformation but the string result of the transform was correct and it was when I then transformed the string to a org.w3c.dom.Document that the default namespaces were being added.
Making the DocumentBuilderFactory namespace aware fixed this
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document metadataDOM = db.parse(new ByteArrayInputStream(stringWriter.toString().getBytes()));
Put the calling template and the applied template in the same namespace.
You're re-defining the default namespace with each of those nodes with the 'xmlns=' declaration. Because the PRIA_DOCUMENT doesn't have a namespace, the output needs to redeclare it as empty, or it would have the same namespace as it's parent. I'd recommend adding in a named namespace to those elements that have one defined, for example:
<pria:DOCUMENT_RECORDATION xmlns:pria="http://pria.org">
and
<as:ONCORE_ERECORD xmlns:as="http://aptitudesolutions.com">
With these named namespaces in place, the blank declaration on the PRIA_DOCUMENT element becomes unnecessary, and is not added.

inserting space in xslt

Hi I am using xslt to show the links on my webpart and i have added plus image next to my link.But I would like to add some space between them. I have added ,but this is not really working. Am i missing anything here? Please find my code below.
Thanks.
<xsl:choose>
<!-- do _self -->
<xsl:when test="contains(Link,'xxx')">
<a target="_self">
<xsl:attribute name="href">
<xsl:value-of select="URL"/>
</xsl:attribute>
<xsl:value-of select="Title"/>
</a>
</xsl:when>
<!-- use _blank (new browser window) -->
<xsl:otherwise>
<a target="_blank">
<xsl:attribute name="href">
<xsl:value-of select="URL"/>
</xsl:attribute>
<xsl:value-of select="Title"/>
</a>
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
<xsl:choose>
<xsl:when test="Description !=' ' ">
<img class="imageclass" src="/images/plus.gif"></img>
</xsl:when>
</xsl:choose>
My understanding is that you want to produce HTML that would display white space in the browser.
If this is so, don't use spaces -- the brouser only displays one single space for a continuous sequence of spaces.
Use nonbreaking space:  
So, instead of:
<xsl:text> </xsl:text>
use:
<xsl:text>   </xsl:text>
The xsl:text instruction is the right tool for your requeriment. As example, this stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="#*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<xsl:call-template name="identity"/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
With this input:
<div>
link1
link1
link1
</div>
Output:
<div>link1 link1 link1 </div>