Changing nodes in XSLT based on context - html

I have one XSL file that I wanna include or use in two different contexts. In one of the contexts I want to use 'fo:block' but in the other context I want to use 'div class="Block"'.
Is there someway to change all my 'fo:block' in my XSL to 'div class="Block"' or vice versa based on the context, maybe with the use of parameters?

Its a simple condition:
<xsl:variable name="outputformat" select="'html'"/>
<xsl:choose>
<xsl:when test="$outputformat = 'html'">
<div class="Block">
<!-- your html code -->
</div>
</xsl:when>
<xsl:otherwise>
<fo:block>
<!-- your normal code -->
</fo:block>
</xsl:otherwise>
</xsl:choose>
Alternatively you can make a second xsl document and copy every node except the
<fo:block/>
which you should change to
<div class="block"/>
This would look like:
<xsl:template match="#*|node()">
<xsl:choose>
<xsl:when test="local-name() = 'block'">
<xsl:element name="div">
<xsl:attribute name="class" select="'Block'"/>
<xsl:apply-templates select="#*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

Related

Using XSL, I need to check links' href value and change if necessary while leaving other attributes alone

The following code does the following:
Finds links
Checks to see if it's a fully pathed link or an email link
If yes, it does nothing.
If no, it checks for a # to see if it's an anchor
If yes, it does nothing.
If no, it concatenates the domain in front.
This works, but if I add another attribute to the link, it strips it out as well. For example: My link
How do I keep the behavior below but also keep the style attribute?
<xsl:template match="a[#href][not(contains(#href, 'http')) and not(contains(#href, 'mailto'))]">
<xsl:choose>
<xsl:when test="starts-with(#href, '#')">
<a href="{#href}" ><xsl:value-of select="." /></a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
I am guessing (!) you want to do something like:
<xsl:template match="a[#href][not(contains(#href, 'http')) and not(contains(#href, 'mailto'))]">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:attribute name="href">
<xsl:if test="not(starts-with(#href, '#'))">
<xsl:value-of select="$domain" />
</xsl:if>
<xsl:value-of select="#href"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
Or possibly just:
<xsl:template match="a/#href[not(contains(., 'http') or contains(., 'mailto') or starts-with(., '#'))]">
<xsl:attribute name="href">
<xsl:value-of select="$domain" />
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
Untested, because no example was provided.

Add Space Before a tag if it is Present in XSLT

Iam creating styles using XSLT for my XML file.
Here is my code:
<xsl:template match="LEXVAR">
<xsl:copy>
<xsl:apply-templates/>
<xsl:choose>
<xsl:when test="./preceding-sibling::LEXVAR">
<span class="neutral">
<xsl:text>, </xsl:text>
</span>
</xsl:when>
<xsl:when test="./preceding-sibling::*">
<span class="neutral">
<xsl:text> </xsl:text>
</span>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:copy>
</xsl:template>
In my case: LEXVAR is tag and it is to be styled, the condition for styling is add a space if any other tag is present before to it or no space is needed.
And the above code is not working, iam new to XSl, can you please help me.?
Thanks in advance.
Try this to solve your issue :
<xsl:template match="LEXVAR">
<span class="exp">
<xsl:if test="./preceding-sibling::*">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:text></xsl:text>
<xsl:apply-templates/>
</span>
I would put the condition into a predicate of the match pattern e.g.
<xsl:template match="LEXVAR[preceding-sibling::*]">
<span><xsl:text> </xsl:text></span>
<xsl:next-match/>
</xsl:template>
Then make sure you have an identity transformation template or other template handing other LEXVAR elements so that the next-match has some template to call.

Facing issues in parsing xml with xslt

I am trying to parse a xml to generate a html report.The problematic section of the xml is as given
<failure message="Management changes link count is not 3$HiHello" type="junit.framework.AssertionFailedError">junit.framework.AssertionFailedError: Management changes link count is not 3$HiHelloJI
at CustomProjects.CommonTemplates.verifyManagementChanges(Unknown Source)
at CustomProjects.EmersonTest.testEmerson_VerifyManagementChanges(Unknown Source)
</failure>
The xslt written for parsing this is :
<xsl:choose>
<xsl:when test="failure">
<td>Failure</td>
<td><xsl:apply-templates select="failure"/></td>
<td>screenshot</td>
<td><xsl:apply-templates select="failurelink"/></td>
</xsl:when>
</xsl:choose>
<xsl:template match="failure">
<xsl:call-template name="display-failures"/>
</xsl:template>
<xsl:template match="failurelink">
<xsl:call-template name="display-failures-link"/>
</xsl:template>
<xsl:template name="display-failures">
<xsl:param name="FailText" select="#message"/>
<xsl:choose>
<xsl:when test="not(#message)">N/A</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($FailText,'$')"/>
</xsl:otherwise>
</xsl:choose>
<!-- display the stacktrace -->
<code>
<br/><br/>
<xsl:call-template name="br-replace">
<xsl:with-param name="word" select="."/>
</xsl:call-template>
</code>
<!-- the later is better but might be problematic for non-21" monitors... -->
<!--pre><xsl:value-of select="."/></pre-->
</xsl:template>
<xsl:template name="display-failures-link">
<xsl:param name="linktext" select="#message"/>
<xsl:choose>
<xsl:when test="not(#message)">N/A</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-after($linktext,'$')"/>
</xsl:otherwise>
</xsl:choose>
<!-- display the stacktrace -->
<code>
<br/><br/>
<xsl:call-template name="br-replace">
<xsl:with-param name="word" select="."/>
</xsl:call-template>
</code>
<!-- the later is better but might be problematic for non-21" monitors... -->
<!--pre><xsl:value-of select="."/></pre-->
</xsl:template>
Here I am getting the desired result(The String before $ sign) from display-failures template but on calling display-failures-link I am getting nothing.(Should get the string after $ sign).I dont know whether the problem is with sunstring function or with something else.Kindly let me know what I am doing wrong here.
Any help is highly appreciated.
The problem here is that you are trying to apply-templates on the XPath failurelink, but you don't have an element called <failurelink>, so this apply-templates isn't finding anything.
<xsl:apply-templates select="failurelink"/>
One way to apply two different templates on the same kind of element is to use modes:
<xsl:template match="failure">
<xsl:call-template name="display-failures"/>
</xsl:template>
<xsl:template match="failure" mode="link">
<xsl:call-template name="display-failures-link"/>
</xsl:template>
Then the area where you apply the templates would change to this:
<td>Failure</td>
<td><xsl:apply-templates select="failure"/></td>
<td>screenshot</td>
<td><xsl:apply-templates select="failure" mode="link"/></td>
But in your case, there's an even better approach. Just eliminate the second template, and do this:
Replace the whole <xsl:choose> with:
<xsl:apply-templates select="failure" />
Replace the first template you listed with:
<xsl:template match="failure">
<td>Failure</td>
<td><xsl:call-template name="display-failures"/></td>
<td>screenshot</td>
<td><xsl:call-template name="display-failures-link"/></td>
</xsl:template>
And delete the second template you listed.

XSLT : How to create conditional link without duplicating code

The generated HTML page contains reference links that sometimes doesn't exist in my page. I should display this link as a simple label.
Currently this is done:
<xsl:choose>
<xsl:when test="$nb_action != 0">
Action (offensive, defensive, reconnaissance)
</xsl:when>
<xsl:otherwise>
Action (offensive, defensive, reconnaissance)
</xsl:otherwise>
</xsl:choose>
I'm wondering how to simplify my code, how to deactivate node <a></a> ?
My first idea was to delegate a special css class :
<a href="#action">
<xsl:if test="$nb_action = 0">
<xsl:attribute name="class">inactive</xsl:attribute>
</xsl:if>Action (offensive, defensive, reconnaissance)
</a>
But it remains a link...
A workaround that follows:
<a><xsl:if test="$nb_action != 0">
<xsl:attribute name="href">#action</xsl:attribute>
</xsl:if>Action (offensive, defensive, reconnaissance)</a>
It is correct to write an html <a> tag without href ?
You could make that Action text as a variable. This variable still appears in 3 places though.
<xsl:variable name="textval">
Action (offensive, defensive, reconnaissance)</xsl:variable>
<xsl:choose>
<xsl:when test="0">
<xsl:copy-of select="$textval"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$textval"/>
</xsl:otherwise>
</xsl:choose>
Edit: Alternatively, if you don't mind an extra, useless span tag, you could use
<xsl:variable name="condition" select="---condition-here---"/>
<xsl:variable name="tagname">
<xsl:choose>
<xsl:when test="$condition">a</xsl:when>
<xsl:otherwise>span</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$tagname}">
<xsl:if test="$condition">
<xsl:attribute name="href">#action</xsl:attribute>
</xsl:if>
Action (offensive, defensive, reconnaissance)
</xsl:element>
(In Firefox, if we set $tagname to an empty string, then the element won't be applied at all. But the processor could also raise an error, so don't rely on it.)
What don't you store the string Action(..) into a variable and it in code?

Tiny mce is adding extra p tags when copied from outlook or word

I think my earlier question was too large, I am trying to put some minimal content.
Problem:
When I am trying to copy some content from word/outlook to tinymce, any text after bullet points/numbers is getting discarded when writing to word.
Example:
When I copy below contnet, I am not seeing Bullet1 and Bullet2 in final word document
Word bullets test IE
• Bullet1
• Bullet2
My xslt code:
<xsl:template match="qnap:li">
<xsl:variable name="paraStyle" as="xs:string">
<xsl:choose>
<xsl:when test="parent::qnap:ol">AnswerNumbered</xsl:when>
<xsl:otherwise>AnswerBullet</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="not(qnap:p)">
<xsl:variable name="paraContent" as="element()">
<span>
<xsl:apply-templates/>
</span>
</xsl:variable>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="paraContent" as="element()">
<span>
<xsl:apply-templates select="qnap:p"/>
</span>
</xsl:variable>
</xsl:otherwise>
</xsl:choose>
Hope this is not creating any confusion. Any help would be much appreciated