Xslt: populate innertext value of <a href="" /> in xslt during runtime - xslt

I tried a lot to see if any suggestion/answer would satisfy my requirement but could not find any.
I have an Xml file which I am using to get an output Html file using XslTransform API and an Xslt stylesheet.
My xml file has a rootnode which will have two attributes - HyperlinkDisplayText and HyperlinkValue. This xml file is generated at runtime. So, the values of these attributes are not known at compile time.
My requirement is that the html output should display a hyperlink whose display text needs to be taken from the value of 'HyperlinkDisplayText' and the hyperlink value needs to be taken from the value of "HyperlinkValue'.
For example,
<RootNode HyperlinkDisplayText="Google" HyperlinkValue="https://www.google.com/" />
This needs to be appears as Google.
For this, I tried several things in my xslt. Below is a snapshot what I am trying in my xslt file -
<xsl:choose>
<xsl:when test="#HyperlinkDisplayText and #HyperlinkValue">
<h4 style="font-family: arial" align='center'>
#HyperlinkDisplayText
</h4>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
It is not working. Any help is highly appreciated.
Regards,
kvk938

Change #HyperlinkDisplayText to <xsl:value-of select="#HyperlinkDisplayText"/>. That assumes the context node is a RootNode element.

Related

How to prevent self closing tags as well empty tags after transforming

I have in an input file:
<a></a>
<b/>
<c>text</c>
I need to converting this to string. Using transformer I am getting below output:
<a/> <!-- Empty tags should not collapse-->
<b/>
<c>text</c>
If I use xslt and output method is "HTML", I get the below output:
<a></a> <!-- This is as expected-->
<b></b> <!-- This is not expected-->
<c>text</c>
I want the structure same as in input file. It is required in my application since I need to calculate index and it will be very difficult to change the index calution logic.
What would be the correct XSLT to use?
What XSLT processor? XSLT is merely a language to transform xml so "html output" is dependent on the processor.
I'm going to guess this first solution is too simple for you but i've had to use this to avoid processing raw html
<xsl:copy-of select="child::node()" />
as this should clone the raw input.
In my case, I have used the following to extract all nodes that had the raw attribute:
<xsl:for-each select="xmlData//node()[#raw]">
<xsl:copy-of select="child::node()" />
</xsl:for-each>
Other options:
2) Add an attribute to each empty node depending on what you want it to do later ie role="long", role="short-hand".
3)
Loop through each node (xsl:for-each)
<xsl:choose>
<xsl:when test="string-length(.)=0"> <!-- There is no child-->
<xsl:copy-of select="node()" />
</xsl:when>
<xsl:otherwise>
...whatever normal processing you have
</xsl:otherwise>
4) Redefine your problem. Both are valid XHTML/XML, so perhaps your problem can be reframed or fixed elsewhere.
Either way, you may want to add more information in your question so that we can reproduce your problem and test it locally.
P.S. Too much text/code to put in a comment, but that's where this would belong.
A possible alternative is to use disable-output-escaping like this:
<xsl:text disable-output-escaping="yes"><a></a></xsl:text>
But I understand that this is a dirty solution...

umbraco: get USER properties, NOT member properties in XSLT

Here's my scenario:
Added an Author Picker to the default umbBlogPost (from the blog4umbraco package) which gives me access to the author's id in an XSLT macro
The Author Picker is pulling up a list of umbraco users, not members
I want to the display the author's username in xslt output
I've tried several different ways based on Google searches which all seem to be using the Membership API, such as umbraco.libary:GetMember and umbraco.library:GetMemberName which is not working, again, as I am dealing with umbraco users, not members. There doesn't appear to be any user equivalent methods, i.e., umbraco.libary:GetUser or umbraco.library:GetUserName.
Does anyone know how I can get user properties in an xslt macro? I am using version 4.7.2. Also, while I'm currently working with xslt, if this can be done with a Razor macro (if supported in 4.7.2?) I am open to seeing this approach as well. Thanks.
Taking a look directly in the XML that the XSLTs run off (~/App_Data/umbraco.config), I found the following attributes:
<Site
writerID="0"
creatorID="0"
writerName="John Smith"
creatorName="John Smith"
/>
So you should be able to reference those in the XSLT with the following:
<xsl:value-of select="$currentPage/#writerName" />
If you need the other properties of the user, you'll probably need to write your own library, which could then be accessed by the XSLT files. Just look at how umbraco.library is included at the top of the file.
Ucomponents provides an XSLT solution
<xsl:choose>
<xsl:when test="$currentPage/bodyAuthor != ''">
<xsl:value-of select="ucomponents.cms:GetUserName($currentPage/bodyAuthor)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$currentPage/#writerName" />
</xsl:otherwise>
</xsl:choose>
I ended up solving this by writing a Razor macro. The key was to add #using umbraco.BusinessLogic; at the beginning of the macro. This namespace provides the API required to get user data as opposed to member data.
For anyone interested, here's the macro I wrote:
#using umbraco.BusinessLogic;
#inherits umbraco.MacroEngines.DynamicNodeContext
<div>
<h1>
From Our Blog
</h1>
<ul>
#foreach(var i in #Model.AncestorOrSelf("umbHomepage").Descendants("umbBlogPost").OrderBy("PostDate desc").Take(5))
{
<li>
<p>
#i.Name<br />
by #umbraco.BusinessLogic.User.GetUser(Int32.Parse(i.blogAuthor)).Name on #i.PostDate.ToString("MMM dd, yyyy")
</p>
</li>
}
</ul>
</div>

How to dynamically assign name and href for anchor tag in xsl

I have a requirement where the xml might have one or more services (name might be different), and I am having a content which should have all of these available services from the xml something like below
<li>CMS</li>
<li>DIS</li>
but above I have hardcoded the a tag content and href since I know these are the values, but in real time I would not be knowing these names, so how to set href and anchor tag contents based on xml values?
So far I got the below for-each statement, which gets me all the service names from the xml
<xsl:variable name="number">
<xsl:number/>
</xsl:variable>
<xsl:for-each select="csmclient/product/domainmetadata/domainmetadata_service">
<li><xsl:value-of select="#name"/><xsl:value-of select="position()"/></li>
</xsl:for-each>
.
.
.
<!--far below end-->
<xsl:for-each select="domainmetadata/domainmetadata_service">
<h3>Service Name: <span style="color:#328aa4"><a name="_ser{$number}" href="#_top"><xsl:value-of select="#name"/></a></span></h3>
.
.
.
</xsl:for-each>
but it does not seem to work, it gives me all my services but the link does not work. Any other ideas?
Note: I took help from this question link which had a similar requirement.
There is a xslt function generate-id() which gives and unique textual identifier for any node in the xml.
http://www.w3.org/TR/xslt#function-generate-id
Use something like below, should work
<xsl:for-each select="csmclient/product/domainmetadata/domainmetadata_service">
<li><xsl:value-of select="#name"/></li>
</xsl:for-each>
<xsl:for-each select="domainmetadata/domainmetadata_service">
<h3>Service Name: <span style="color:#328aa4"><a name="{generate-id()}" href="#_top"><xsl:value-of select="#name"/></a></span></h3>
</xsl:for-each>
<li><xsl:value-of select="#name"/><xsl:value-of select="position()"/></li>
but it does not seem to work ...
What you are trying to write is this (not discussing at all if this uniquely identifies the node):
<li>
<a href="#_ser{$number}{#name}{position()}"/>
</li>

C# .xsl view from xml -- only outputs the first element

I'm learning on the fly, and I have commented C# code with /// that generates xml after:
csc Class1.cs /out:Class1Docs /rescurse:*.cs /doc:Class1Doc.xml
My xsl file (the relevant part) is like so:
<xsl:for-each select="doc">
<br>
<xsl:value-of select="members/member"/>
</br>
<br>
<xsl:value-of select="summary"/>
</br>
</xsl:for-each>
</body>
</html>
</xsl:template>
The problem is that I need to output the member, summary, params, and return value.
I only get the 'member/member' returned:
Class1 Class
How do i select the xsl:value of for each tag ?
My xsl file (the relevant part) is
like so:
<xsl:for-each select="doc">
<br>
<xsl:value-of select="members/member"/
</br>
<br>
<xsl:value-of select="summary"/>
</br>
</xsl:for-each>
</body>
</html>
</xsl:template>
This is badly malformed XML!
Let's think that the relevant, well-formed portion is:
<xsl:for-each select="doc">
<br>
<xsl:value-of select="members/member"/>
</br>
<br>
<xsl:value-of select="summary"/>
</br>
</xsl:for-each>
There are many problems with this code:
AFAIK the (x)HTML element br should have no content. Maybe you wanted:
<xsl:value-of select="members/member"/>
The <xsl:value-of> instruction creates a text node that contains the string value of the first node only, that is specified in the XPath expression in the select attribute.
Probably you wanted:
<xsl:copy-of select="members/member/text()"/>
.3. Specifying all literal result elements and using <xsl:for-each> within a single template is not a good XSLT programming practice. It is recommended to use more templates and correspondingly, <xsl:apply-templates> instead of <xsl:for-each>.
I can't really post the whole XML example because it's internal info
Then it's easy enough to provide an example that exhibits all the necessary properties of the real data, surely? You can't expect people to help you with one hand tied behind their backs.
Like other responders, I'm guessing, but my guess is that you failed to realise that in XSLT 1.0, the xsl:value-of instruction only outputs the string value of the first node in the sequence. If for some reason you can't move to XSLT 2.0, you need to put the xsl:value-of inside an xsl:for-each or xsl:apply-templates loop.

How to generate link with XSLT

Hi i've made a php webservice that returns some xml which is transformed into html by an XML file i have . But i want to be able to click on each returned item to get more details about that item. <?php echo $itemname"?>
Recently i did the same thing but in PHP, ive tried to use this in XSLT but it doesn't work.
Use xsl:attribute:
<a>
<xsl:attribute name="href">item.php?id=<xsl:value-of select="ItemId" /></xsl:attribute>
<xsl:value-of select="ItemName" />
</a>
Alternatively, the shorter form:
<xsl:value-of select="ItemName" />
Should also work