A question about templates for specialized elements

Here should go questions about transforming XML with XSLT and FOP.
surangamas
Posts: 47
Joined: Tue Feb 21, 2012 10:17 pm

A question about templates for specialized elements

Post by surangamas »

Hi, I also posted this question on the Yahoo DITA user group board.

This is a question I've always wanted to ask but never had a chance to
do so, partly because I didn't really think this could be a problem until now.

Long story short: I've created a new specialized element called <artifact_type>
based off <codeph>, and I want <artifact_type> to output in bold, monospaced
font. I've already defined an attribute set for <artifact_type> in a new
stylesheet and imported it in my custom.xsl. I wrote a template that points
directly to the name of the specialized element. However when I applied the
template I wrote, the output still uses the style defined for <codeph>
(monospaced but NOT bolded). Here is the template in question:

<!-- template No.1 -->
<xsl:template match="*[contains(@class, ' myDomain/artifact_type ')]">
<fo:inline xsl:use-attribute-sets="artifact_type" id="{@id}">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>

But if I required my users to manually input a value of "sp" in the @outputclass
field of <artifact_type>, and applied the following template, the output was as
expected:

<!-- template No.2 -->
<xsl:template match="*[contains(@class, ' pr-d/codeph ')]">
<xsl:choose>
<xsl:when test="@outputclass='sp'">
<fo:inline xsl:use-attribute-sets="artifact_type" id="{@id}">
<xsl:apply-templates/>
</fo:inline>
</xsl:when>
<xsl:otherwise>
<fo:inline xsl:use-attribute-sets="codeph" id="{@id}">
<xsl:apply-templates/>
</fo:inline>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

However, I don't want to use the template above, because users are forced to
remember that they need to manually input a value in the @outputclass field,
which undermines their user experiences. Is it possible to write a template that
points directly to the name of the specialized element, the same way that
template No.1 above demonstrates? I've tried this with DITA-OT v. 1.4.2.1 and
also with the latest v.1.5.4, but to no avail. Any help from this group is
appreciated.

p.s. I also must mention that I placed the specialized template in the override stylesheet.
Radu
Posts: 9439
Joined: Fri Jul 09, 2004 5:18 pm

Re: A question about templates for specialized elements

Post by Radu »

Hi,

So what I think is that when you define your template in the "custom.xsl" like:

Code: Select all

<xsl:template match="*[contains(@class, ' pr-d/codeph ')]">...
it will perfectly overwrite the template defined in the standard DITA XSLs and it will get called instead of it.

But when you define it like:

Code: Select all

<xsl:template match="*[contains(@class, ' myDomain/artifact_type ')]">
it is just another template which in some situations matches the same nodes as the template defined in the common XSL code.
This case is called a conflict:

http://www.w3.org/TR/xslt#conflict

In this case you can increase the priority of the template like:

Code: Select all

<xsl:template match="*[contains(@class, ' myDomain/artifact_type ')]" priority="1000">
I tested and it should work.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
surangamas
Posts: 47
Joined: Tue Feb 21, 2012 10:17 pm

Re: A question about templates for specialized elements

Post by surangamas »

Hi Radu:
Thanks for the reply; however setting priority to a higher number doesn't seem to work either, it still grabbed the attribute set for <codeph> and applied it to <artifact_type>, any ideas?
Radu
Posts: 9439
Joined: Fri Jul 09, 2004 5:18 pm

Re: A question about templates for specialized elements

Post by Radu »

Hi,

If you edit directly the DITA-OT/demo/fo/xsl/fo/pr-domain.xsl stylesheet and completely comment out the xsl:template:

Code: Select all

 <xsl:template match="*[contains(@class,' pr-d/codeph ')]">
<fo:inline xsl:use-attribute-sets="codeph">
<xsl:call-template name="commonattributes"/>
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
does your custom template get called? If not, maybe your match selector is not correct.
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
surangamas
Posts: 47
Joined: Tue Feb 21, 2012 10:17 pm

Re: A question about templates for specialized elements

Post by surangamas »

Hi Radu:
I completely commented out the template for <codeph>, and ran the transform again, the specialized element <artifact_type> still didn't get the attributes I set for it. You mentioned that maybe the match selector was incorrectly set, what could be wrong with my match selector, could you please check? Below is my template for the specialized element, thanks.

The template of my specialized element is in DITA-OT/demo/fo/cfg/fo/xsl/custom.xsl:

I've also created a file called "custom-domain-attr.xsl" which is stored in the same directory as custom.xsl, and I did a <xsl:import> that points to that file in custom.xsl. In "custom-domain-attr.xsl", I have defined an attribute set called "artifact_type".

<xsl:template match="*[contains(@class, ' txvia-d/artifact_type ')]">
<fo:inline xsl:use-attribute-sets="artifact_type" id="{@id}">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>

Could you point out what I did wrong above? Thanks.
surangamas
Posts: 47
Joined: Tue Feb 21, 2012 10:17 pm

Re: A question about templates for specialized elements

Post by surangamas »

Hi Radu:
You are absolutely right about the match selector being incorrectly set; I changed it from "txvia-d/artifact_type" to simply "artifact_type", and it was working! Thanks for pointing out the root cause of the problem, you have my highest regard :)
Post Reply