Reputation: 6806
I almost have my transform working but the final piece is eluding me.
My input XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE reference PUBLIC "-//OASIS//DTD DITA Reference//EN"
"/SysSchema/dita/dtd/technicalContent/dtd/reference.dtd">
<reference xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/"
ditaarch:DITAArchVersion="1.2" xml:lang="en-US" id="doc">
<title>Title</title>
<refbody>
<section>
<draft-comment outputclass="PHP" translate="no">//
Comment</draft-comment>
<sectiondiv><ph id="r1">A</ph></sectiondiv>
<sectiondiv><ph id="r2">B</ph></sectiondiv>
</section>
<section>
<sectiondiv><ph id="r3" conref="#doc/r1" /></sectiondiv>
<sectiondiv><ph id="r4" conref="#doc/r2" /></sectiondiv>
<sectiondiv><ph id="r5">C</ph></sectiondiv>
</section>
</refbody>
</reference>
The goal is to get this out:
<?php if (! defined('BASEPATH')) exit('No direct script access allowed');
// Comment
$lang['r1'] = 'A';
$lang['r2'] = 'B';
$lang['r3'] = 'A';
$lang['r4'] = 'B';
$lang['r5'] = 'C';
Where the PH tags with a CONREF output the referred-to PH's value.
My current XSLT is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no" omit-xml-declaration="yes" />
<!-- strip all white space -->
<xsl:strip-space elements="*" />
<!-- remove unnecessary tags -->
<xsl:template match="section">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="sectiondiv">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="refbody">
<xsl:apply-templates />
</xsl:template>
<!-- Copy XML -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- Add PHP script access code-->
<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><?php if (! defined('BASEPATH')) exit('No direct script access allowed');</xsl:text>
<xsl:text>

</xsl:text>
<xsl:apply-templates select="/reference/refbody" />
</xsl:template>
<!-- Convert draft-comment to php comment -->
<xsl:template match="//draft-comment[@outputclass='PHP']">
<xsl:value-of select="." />
<xsl:text>
</xsl:text>
</xsl:template>
<!-- Replace ph with $lang variables -->
<xsl:template match="sectiondiv/ph[not(@conref)]">$lang['<xsl:value-of select="@id" />'] = '<xsl:value-of select="." disable-output-escaping="yes" />';<xsl:text>
</xsl:text></xsl:template>
<!-- Replace ph with $lang variables -->
<xsl:template match="sectiondiv/ph[@conref]">$lang['<xsl:value-of select="@id" />'] = '<xsl:value-of select="//ph[@conref]" disable-output-escaping="yes" />';<xsl:text>
</xsl:text></xsl:template>
</xsl:stylesheet>
The last part with match="sectiondiv/ph[@conref]"
is the issue. I have tried using a variable ala:
<xsl:template match="sectiondiv/ph[@conref]"><xsl:variable name="refid" select="@conref" />$lang['<xsl:value-of select="@id" />'] = '<xsl:value-of select="//ph[$refid]" disable-output-escaping="yes" />';<xsl:text>
</xsl:text></xsl:template>
which seemed promising until I found out that an XSL "variable" is actually a runtime constant, and I was getting:
<?php if (! defined('BASEPATH')) exit('No direct script access allowed');
// Comment
$lang['r1'] = 'A';
$lang['r2'] = 'B';
$lang['r3'] = 'A';
$lang['r4'] = 'A';
$lang['r5'] = 'C';
I also tried using <xsl:value-of select="//ph[string(@conref)]" disable-output-escaping="yes" />
I'm sure there's an easy solution, but I am not familiar with XSL (so naturally I'm the one who gets to work on it.)
P.S. Sorry for the long-lines, but I am additionally having many issues with line breaks being inserted where I cannot tolerate them, so this was the best fix I found so far.
P.P.S Sorry for the lack of syntax highlighting but I could not seem to get it working.
Upvotes: 0
Views: 278
Reputation: 23627
You have to extract the id from the @conref
attribute, and then compare it to the @id
of the ph
you want to replace. You can use a variable to save the extracted ID:
<xsl:template match="sectiondiv/ph[@conref]">
<xsl:variable name="id" select="substring-after(@conref, '#doc/')"/>
...
And then use it to select which ph
element will be replaced:
<xsl:value-of select="//ph[$id = @id]" />
You should also place your text within <xsl:text>
to control the spaces in your output. Replace these templates in your XSL and you should obtain the result you expect:
<!-- Replace ph with $lang variables -->
<xsl:template match="sectiondiv/ph[not(@conref)]">
<xsl:text>$lang['</xsl:text><xsl:value-of select="@id" /><xsl:text>'] = '</xsl:text>
<xsl:value-of select="." disable-output-escaping="yes" />
<xsl:text>';
</xsl:text>
</xsl:template>
<!-- Replace ph with $lang variables -->
<xsl:template match="sectiondiv/ph[@conref]">
<xsl:variable name="id" select="substring-after(@conref, '/')"/>
<xsl:text>$lang['</xsl:text><xsl:value-of select="@id" /><xsl:text>'] = '</xsl:text>
<xsl:value-of select="//ph[$id = @id]" disable-output-escaping="yes" />
<xsl:text>';
</xsl:text>
</xsl:template>
Upvotes: 1