How to get XSLT and XPath to output XML in granular HTML manipulation within Symphony CMS

StackOverflow https://stackoverflow.com/questions/11281569

Вопрос

Within Symphony CMS, I want to be able to have an XML document which contains page content (probably using DocBook) and another XML document which is a central acronym/abbreviation repository. This repository, for example could look like this:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../utilities/master.xsl"?>
<terminology>
    <abbreviations>
        <term abbr="World Wildlife Fund">WWF</term>
    </abbreviations>
</terminology>

An XSL document will then perform transforms with XPath to display the DocBook XML within templates.

For example, within the copy that is output from the DocBook contains the text ‘WWF,’ whenever this occurs, the XSLT and XPath wraps that word with an abbreviation tag with a title using the acronym/abbreviation repository as a resource.

<abbr title="World Wildlife Fund">WWF</abbr>

The whole setup needs to be extendable enough to have a whole bunch of terms in the repository that can be called upon whenever a certain string of text is seen within the DocBook content.

I have been pointed in the direction of the HTML Ninja Technique which sounds as though it will provide me with what I need, but the example is pulling in HTML (which seems a bit odd) and does not go into detail about how to perform the kind of manipulation on strings of text I am looking to produce.

It is worth noting, I have been attempting to do this within a master.xsl template in Symphony Utilities. I am happy to be corrected if this won't work within this file.

I am very new to XSLT and XPath, so please don't assume anything of my knowledge when answering this. I am even struggling to wire up the XML and XLS documents at this time. Step-by-step instructions to allow me to produce a proof of concept will be appreciated.

Это было полезно?

Решение

Assuming that I have 3 set of files at same location.

  1. Page Document (XML).

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="transform.xsl"?>
    <html>
        <span>WWF1</span>
        <span>WWF</span>
        <span>WWF2</span>
    </html>
    
  2. Acronym Repository (XML)

    <?xml version="1.0"?>
    <terminology>
      <abbreviations>
        <term abbr="World Wildlife Fund 1">WWF1</term>
        <term abbr="World Wildlife Fund 2">WWF2</term>
      </abbreviations>
    </terminology>
    
  3. Transformer (XSL).

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml"/>
       <xsl:template match="/">
          <xsl:apply-templates select="html" mode="transform">
             <xsl:with-param name="repository" select="document('repository.xml')/terminology"/>
          </xsl:apply-templates>
       </xsl:template>
    
      <!-- Updated Template Start-->
      <xsl:template match="text()" mode="transform" priority="2.5">
         <xsl:param name="repository" />
         <xsl:variable name="this" select="." />
         <xsl:variable name="term" select="$repository/abbreviations/term[contains($this,./text())]" />
         <xsl:choose>
            <xsl:when test="count($term) > 0">
           <xsl:value-of select="substring-before(., $term/text())"/>
               <xsl:variable name="termTitle" select="$term/@abbr" />
               <abbr title="{$termTitle}"><xsl:value-of select="$term/text()"/></abbr>
       <xsl:value-of select="substring-after($this, $term/text())"/>
            </xsl:when>
            <xsl:otherwise>
               <xsl:copy-of select="."/>
            </xsl:otherwise> 
         </xsl:choose>
       </xsl:template>
       <!-- Updated Template Stop-->
    
       <xsl:template match="node()" mode="transform" priority="2">
          <xsl:param name="repository" />
          <xsl:copy>
             <xsl:apply-templates mode="transform">
                <xsl:with-param name="repository" select="$repository"/>
             </xsl:apply-templates>
          </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

The transformer file would give an output like the following.

<html>
  <span><abbr title="World Wildlife Fund 1">WWF1</abbr></span>
  <span>WWF</span>
  <span><abbr title="World Wildlife Fund 2">WWF2</abbr></span>
</html>

You can scale the acronym by simply adding another node.

The XSLT need not be changed.

I hope this helps you.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top