I’m trying to process XML inner text. I have the following XSLT snippet:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="refsect1[@id='errors']/param">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="param/constant">
<i><xsl:apply-templates/></i>
</xsl:template>
<xsl:template match="param/parameter">
<paramref cref="{.}"/>
</xsl:template>
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:template name="summary" match="refentry">
/// <summary>
/// <xsl:value-of select="concat(translate(
substring(refnamediv/refpurpose, 1, 1), $lowercase, $uppercase),
substring(refnamediv/refpurpose, 2, string-length(refnamediv/refpurpose) - 1))"/>
/// </summary>
<xsl:for-each select="refsect1/variablelist/varlistentry">
<xsl:choose>
<xsl:when test="../../@id = 'parameters'">
/// <param name="{term/parameter}">
<xsl:for-each select="listitem/para">
/// <xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
/// </param>
</xsl:when>
</xsl:choose>
</xsl:for-each>
/// <remarks>
/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError"/>):
<xsl:for-each select="refsect1[@id='errors']/para">
/// <xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
/// </para>
/// </remarks>
<xsl:for-each select="refsect1[@id = 'seealso']/para/citerefentry">
/// <seealso cref="Gl.{substring(refentrytitle, 3)}"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This XSLT shall be applied to a XML document; here is a snippet:
<refsect1 id="errors"><title>Errors</title>
<para>
<constant>GL_INVALID_OPERATION</constant> is generated if <parameter>pipeline</parameter> is not
a name previously returned from a call to <citerefentry><refentrytitle>glGenProgramPipelines</refentrytitle></citerefentry>
or if such a name has been deleted by a call to
<citerefentry><refentrytitle>glDeleteProgramPipelines</refentrytitle></citerefentry>.
</para>
<para>
<constant>GL_INVALID_OPERATION</constant> is generated if <parameter>program</parameter> refers
to a program object that has not been successfully linked.
</para>
</refsect1>
My current output is actually a plain text:
/// <remarks>
/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError" />):
/// GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call to glGenProgramPipelines or if such a name has been deleted by a call to glDeleteProgramPipelines.
/// GL_INVALID_OPERATION is generated if program refers to a program object that has not been successfully linked.
/// </para>
/// </remarks>
but I’d like to to process it in order to transform the internal tags in other tags. For example:
<costant>text</constant> shall become <i>text</i>
and
*<parameter>GL_PARAM</parameter>* shall become <paramref cref=”Gl.PARAM”/>
How to achieve this result?
After that Alexander has helped me, I got I have to call xsl:apply-template. It starting to work, but I cannot control the space normalization:
/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError" />):
<i>GL_INVALID_OPERATION</i> is generated if <paramref cref="pipeline" /> is not
a name previously returned from a call to glGenProgramPipelines
or if such a name has been deleted by a call to
glDeleteProgramPipelines.
<i>GL_INVALID_OPERATION</i> is generated if <paramref cref="program" /> refers
to a program object that has not been successfully linked.
/// </para>
I’m calling xsl:apply-template just after the foreach instruction:
/// <para>
/// This routine generates the following errors (detectable with <see cref="Gl.GetError"/>):
<xsl:for-each select="refsect1[@id='errors']/para">
<xsl:apply-templates/>
</xsl:for-each>
/// </para>
Part of the trick is to understand the power of functional and declarative programming. You’ve got a very imperative style at the moment, so let’s rewrite it a bit ;
That’s roughly all you need. Basically, instead of going through all parts of your XML and try to do something at that point, use the templating system to match the items in question and have it done far more efficient and powerful.
Lastly, if your GL_PARAM to Gl.PARAM wasn’t a typo, you need to do some extra text transformation on top, but it isn’t that hard if you know the formula (you didn’t say :), using something like before-substring(), after-substring(), and translate().