XSL Output Text - xslt

<xsl:for-each select="$all_events[g:active = true()][g:body/g:current = true()]">
<xsl:for-each select="g:body">
<h2 class="normal"><xsl:value-of select="g:sub_title" /></h2>
<xsl:for-each select="g:paragraphs">
<xsl:text><xsl:value-of select="g:paragraph" /></xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
Here is my XSL, take notice to the following line:
<xsl:text><xsl:value-of select="g:paragraph" /></xsl:text>
I tried this because the g:paragraph is coming from a WYSIWYG and it was printing out the <p> </p> tags and whatever else. This process of encapsulating it within xsl:text tags caused an error. What is the proper way to either hide the tags (because I want the styles to still be applied if included (i.e. bold, underlined)?
Edit:
The output currently is <p>whatever</p>
I want it to be whatever

Ah, I figured it out. I just had to use disable-output-escaping="yes"

You want to select the text content from a p element inside the g:paragraph element. You can do that this way:
<xsl:for-each select="g:paragraphs">
<xsl:value-of select="g:paragraph/p" />
</xsl:for-each>

Related

XSLT for-each, iterating through text and nodes

I'm still learning XSLT, and have a question about the for-each loop.
Here's what I have as far as XML
<body>Here is a great URL<link>http://www.somesite.com</link>Some More Text</body>
What I'd like is if the for-each loop iterate through these chunks
1. Here is a great URL
2. http://www.somesite.com
3. Some More Text
This might be simple, or impossible, but if anyone can help me out I'd appreciate it!
Thanks,
Michael
You should be able to do so with something like the following:
<xsl:for-each select=".//text()">
<!-- . will have the value of each chunk of text. -->
<someText>
<xsl:value-of select="." />
</someText>
</xsl:for-each>
or this may be preferable because it allows you to have a single template that you can invoke from multiple different places:
<xsl:apply-templates select=".//text()" mode="processText" />
<xsl:template match="text()" mode="processText">
<!-- . will have the value of each chunk of text. -->
<someText>
<xsl:value-of select="." />
</someText>
</xsl:for-each>

xslt matching and stripping

I have a XML structure like this, just some valid XML structure mixed with HTML tags. I am trying to match <p>MyHeader</p> in the section and set it to empty.
That is after running the XSLT on this structure, i don't want to print the <p>MyHeader</p> tag.
<abstract>
<section>
<p>MyHeader</p>
<p> other content in section </p>
<h1> other content in section </h1>
</section>
</abstract>
Here's what I am trying in the XSL
<xsl:template match="abstract/section/p">
<xsl:choose>
<xsl:when test="text() ='MyHeader'"></xsl:when>
<xsl:otherwise><xsl:apply-templates /></xsl:otherwise>
</xsl:choose>
</xsl:template>
any ideas on what's wrong with my code above? I dont see <p>MyHeader</p> tag being stripped out.
<xsl:template match="abstract/section/p">
<xsl:choose>
<xsl:when test="text() ='MyHeader'"></xsl:when>
<xsl:otherwise><xsl:apply-templates /></xsl:otherwise>
</xsl:choose>
</xsl:template>
what's wrong with my code
Nothing wrong with the code shown -- the problem is in the code you haven't shown to us.
Guessing:
The template isn't selected for execution.
There is an explicit <xsl:copy-of> selecting this p element.
Recommendation: just use:
<xsl:template match="abstract/section/p[.='MyHeader']"/>

Using a link in XSL Files

I am completely new to XML so hopefully my explanations will make sense..
I am using an XSL file with 2 sections of HTML text, reading from 2 templates set up within the file.
The first text and associated template is a table, and I have set up a link within that. I want the link to then point to a picture that is part of the 2nd HTML text/template.
The link in the table is setup in that it appears as a link, underlined, etc. However it doesnt go anywhere when clicked.
The second section works fine on it's own, eg, pictures and text appears.
But what I cant figure out is how to actually get the link to work. I've tried numerous things but nothing has worked so far. And I-m not sure whether I am very close and just perhaps need to alter a line of code. Or whether I need to be doing something very different. Also, there are no error messages, and everything displays well, it's just the link itself that doesnt work.
<xsl:template match="portion">
<tr>
<td valign="top"><xsl:value-of select="food-description"/></td>
<td valign="top"><xsl:value-of select="food-number"/></td>
<!--the following is the link text-->
<td valign="top"><a><xsl:attribute name="href">#<xsl:value-of select="portion- photo/#file"/></xsl:attribute>
<xsl:value-of select="portion-photo/#file"/></a><br/>
</td>
</tr>
</xsl:template>
<xsl:template match="portion-photo">
<!--I know that this is the code that is not correct, however, believe it should be something similar-->
<a><xsl:attribute name="portion-photo"><xsl:value-of select="./#file"/></xsl:attribute></a>
<p><xsl:value-of select="../food-description"/>
<xsl:value-of select="./#file"/></p>
<img>
<xsl:attribute name="src"><xsl:value-of select="./#file"/></xsl:attribute>
<xsl:attribute name="width"><xsl:value-of select="ceiling(./#w div v2)"/></xsl:attribute>
<xsl:attribute name="height"><xsl:value-of select="ceiling(./#h div 2)"/></xsl:attribute>
</img>
</xsl:template>
Something like the following should work. Just add the missing name attribute to the anchor element:
<xsl:template match="portion">
...
<a href="#{portion-photo/#file}">
<xsl:value-of select="portion-photo/#file"/>
</a>
...
</xsl:template>
<xsl:template match="portion-photo">
<a name="{#file}">
<xsl:value-of select="#file"/>
</a>
</xsl:template>
However, you have to ensure that #file evaluates to a valid anchor name. If the values of all file attributes are unique, you could also create save IDs with generate-id():
<xsl:template match="portion">
...
<a href="#{generate-id(portion-photo)}">
<xsl:value-of select="portion-photo/#file"/>
</a>
...
</xsl:template>
<xsl:template match="portion-photo">
<a name="{generate-id()}">
<xsl:value-of select="#file"/>
</a>
</xsl:template>

Need XSLT for multi-line item

I already tried a lot of things here on stack overflow but I still face the same problem.
Let me try to explain my issue and what I need to achieve. For this I have the following XML:
<authorizationGroups>
<authorizationGroup> <!-- can be multiple -->
<name>OGroup 1</name>
<application> <!-- can be multiple -->
<uid>646</uid>
<applicationFunctions> <!-- can be multiple -->
<name>auth function 11</name>
<name>auth function 12</name>
</applicationFunctions>
</application>
<role>5000682864</role>
<role>5000685391</role>
</authorizationGroup>
<authorizationGroup> <!-- can be multiple -->
<name>OGroup 8</name>
<application> <!-- can be multiple -->
<uid>646</uid>
<applicationFunctions> <!-- can be multiple -->
<name>auth function 13</name>
<name>auth function 14</name>
</applicationFunctions>
</application>
<role>5000683374</role>
<role>5000685391</role>
</authorizationGroup>
I need to get out something like this:
<resource-types>
<resource-types>
<resource-type>
<name>OGroup 1</name>
<actions>
auth function 11,
auth function 12
</actions>
</resource-type>
<resource-type>
<name>OGroup 8</name>
<actions>
auth function 13,
auth function 14
</actions>
</resource-type>
</resource-types>
My problem is that when I use the XSLT I always end up with all the "auth functions xx" within one .
My current code snippet looks like this (there is obviously more than this part):
<resource-types>
<xsl:call-template name="resource_types"/>
</resource-types>
<xsl:template name="resource_types">
<resource-types>
<xsl:for-each select="/authorizationGroups/authorizationGroup/name">
<resource-type>
<name>
<xsl:value-of select="text()"/>
</name>
<actions>
<xsl:for-each select="/authorizationGroups/authorizationGroup/application/applicationFunctions">
<xsl:value-of select=".//text()"/>
,
</xsl:for-each>
</actions>
</resource-type>
</xsl:for-each>
</resource-types>
</xsl:template>
Now I receive all "auth functions xx" in one go. My understanding of XSLT is limited, so my main question is how can I limit the search for the to the part of the XML document I am in.
I assumed that this was a very easy action, but after three days research on the net and stack overflow I haven't come up with an answer.
cu
Andreas
The issue is, I think, is that you are iterating over name elements, like so...
<xsl:for-each select="/authorizationGroups/authorizationGroup/name">
However, when you come to get the applicationFunctions within this xsl:for-each, you do this...
<xsl:for-each
select="/authorizationGroups/authorizationGroup/application/applicationFunctions">
Because of the forward slash at the start of the expression, this will get all applicationFunctions relative to the root of the document, and not the authorizationGroup you are currently in.
What you need to do is this...
<xsl:for-each select="../application/applicationFunctions">
The .. is to get the parent element, because you are currently positioned on the name element which is at the same level as the application element.
Actually, what would be slighty better would be it initially itereate over authorizationGroup to start with
<xsl:for-each select="/authorizationGroups/authorizationGroup">
And then iterate over the applicationFunctions like so
<xsl:for-each select="application/applicationFunctions">
Either enclose the line break in <xsl:text> like (untested):
<xsl:for-each select="/authorizationGroups/authorizationGroup/application/applicationFunctions">
<xsl:value-of select=".//text()"/>
<xsl:text>,
</xsl:text>
</xsl:for-each>
or include it as an escape in <xsl:value-of> like (untested):
<xsl:value-of select="concat(.//text(), ',
')"/>

Hyperlinks within XSLT Templates

I am trying to create hyperlinks using XML information and XSLT templates. Here is the XML source.
<smartText>
Among individual stocks, the top percentage gainers in the S. and P. 500 are
<smartTextLink smartTextRic="http://investing.domain.com/research/stocks/snapshot
/snapshot.asp?ric=HBAN.O">Huntington Bancshares Inc</smartTextLink>
and
<smartTextLink smartTextRic="http://investing.domain.com/research/stocks/snapshot
/snapshot.asp?ric=EK">Eastman Kodak Co</smartTextLink>
.
</smartText>
I want the output to look like this, with the company names being hyperlinks based on the "smartTextLink" tags in the Xml.
Among individual stocks, the top percentage gainers in the S.&P. 500 are Eastman Kodak Co and Huntington Bancshares Inc.
Here are the templates that I am using right now. I can get the text to display, but not the hyperlinks.
<xsl:template match="smartText">
<p class="smartText">
<xsl:apply-templates select="child::node()" />
</p>
</xsl:template>
<xsl:template match="smartTextLink">
<a>
<xsl:apply-templates select="child::node()" />
<xsl:attribute name="href">
<xsl:value-of select="#smartTextRic"/>
</xsl:attribute>
</a>
</xsl:template>
I have tried multiple variations to try to get the hyperlinks to work correctly. I am thinking that the template match="smartTextLink" is not being instantiated for some reason. Does anyone have any ideas on how I can make this work?
EDIT: After reviewing some of the answers, it is still not working in my overall application.
I am calling the smartText template from within my main template
using the following statement...
<xsl:value-of select="marketSummaryModuleData/smartText"/>
Could this also be a part of the problem?
Thank you
Shane
Either move the xsl:attribute before any children, or use an attribute value template.
<xsl:template match="smartTextLink">
<a href="{#smartTextRic}">
<xsl:apply-templates/>
</a>
</xsl:template>
From the creating attributes section of the XSLT 1 spec:
The following are all errors:
Adding an attribute to an element after children have been added to it; implementations may either signal the error or ignore the attribute.
Try this - worked for me:
<xsl:template match="smartText">
<p class="smartText">
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="smartTextLink">
<a>
<xsl:attribute name="href">
<xsl:value-of select="#smartTextRic"/>
</xsl:attribute>
<xsl:value-of select="text()"/>
</a>
</xsl:template>
Trick is - <xsl:attribute> first, before you do any other processing.
Marc