XSLTOperation and sourceLocation

Post here questions and problems related to oXygen frameworks/document types.
mboudreau
Posts: 68
Joined: Sat Jan 07, 2017 1:23 am

XSLTOperation and sourceLocation

Post by mboudreau »

I have created an XSLTOperation action that wraps the content of a table <entry> in a <styled-content> element, using this XSLT stylesheet:

Code: Select all

<xsl:stylesheet 
    xmlns:mml="http://www.w3.org/1998/Math/MathML"
    xmlns:oxy="http://www.oxygenxml.com/ns/author/xpath-extension-functions"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs oxy" version="2.0">

    <xsl:template match="/">
        <xsl:apply-templates select="oxy:current-element()"/>
    </xsl:template>

    <xsl:template match="entry">
        <xsl:copy copy-namespaces="no">
            <xsl:for-each select="@*">
                <xsl:copy/>
            </xsl:for-each>
            <xsl:element name="styled-content">
                <xsl:attribute name="specific-use" select="string('row-header')"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:copy>
    </xsl:template>

    <!-- catchall -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
This works as expected when I place the cursor in the table cell but not inside any child element of the cell. However, for ease of use, I'd like to be able to place the cursor anywhere inside the table cell. For example, if the cell looks like this--

Code: Select all

<entry><italic>Passer domesticus</italic></entry>
--I'd like to be able to be able to place the cursor inside the italic phrase. I tried to enable this by setting the sourceLocation parameter to 'ancestor-or-self::entry', but that doesn't work. Is there a way to do this?
Radu
Posts: 9057
Joined: Fri Jul 09, 2004 5:18 pm

Re: XSLTOperation and sourceLocation

Post by Radu »

Hi,

This is for Jats XML content, right?
I tested on my side with a Jats table with cells named "td", an XSLT like this:

Code: Select all

<xsl:stylesheet 
    xmlns:mml="http://www.w3.org/1998/Math/MathML"
    xmlns:oxy="http://www.oxygenxml.com/ns/author/xpath-extension-functions"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs oxy" version="2.0">

    <xsl:template match="td">
        <xsl:copy copy-namespaces="no">
            <xsl:for-each select="@*">
                <xsl:copy/>
            </xsl:for-each>
            <xsl:element name="styled-content">
                <xsl:attribute name="specific-use" select="string('row-header')"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:copy>
    </xsl:template>

    <!-- catchall -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
applied using an XSLTOperation with both "sourceLocation" and "targetLocation" parameters set to "ancestor-or-self::td" and it seemed to work for me.

Because in what you were trying to do this XSLT template:

Code: Select all

 <xsl:template match="/">
        <xsl:apply-templates select="oxy:current-element()"/>
    </xsl:template>
we expand the oxy:current-element() to the element at the caret position, in your case the "italic" element, meaning that the "td" is no longer processed as you match the "/" (which is the "td" in this case) and then apply the template on the element at caret.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
mboudreau
Posts: 68
Joined: Sat Jan 07, 2017 1:23 am

Re: XSLTOperation and sourceLocation

Post by mboudreau »

Thanks, Radu. I removed the match="/" template from my transformation, and now I get the result I was hoping for.

However, now I'm unclear about the purpose of that template:

Code: Select all

<xsl:template match="/">
        <xsl:apply-templates select="oxy:current-element()"/>
 </xsl:template>
Is it accurate to say that it means "Within the content of the root element, apply the matching templates only to the element currently containing the cursor"? I copied the template from the documentation at https://www.oxygenxml.com/doc/versions/ ... tions.html but given that my current action works without it, I'm not clear when I would need it.
Radu
Posts: 9057
Joined: Fri Jul 09, 2004 5:18 pm

Re: XSLTOperation and sourceLocation

Post by Radu »

Hi,

About the use of that oxy:current-element() XSLT function, our docs says something like this:
There may be situations where you want to look at an ancestor of the current element and make decisions in the script based on that. To do this, you can set the sourceLocation to point to an ancestor node then use the oxy:current-element() function to access the current element
So let's say you have the XML:

Code: Select all

<td id='abc'><b>bold text</b></td>
You place the caret inside the bold text and you want to make changes to it based on the @id attribute value from the parent <td> element.
You would set "sourceLocation" to be "parent::td", targetLocation to be "." and the XSLT would receive the entire <td> element on the "xsl:template match="/"" but it would need to produce only the content of the modified <b> element, so depending on the value of the <td> @id attribute it would apply the templates on the oxy:current-element().

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply