SlideShare a Scribd company logo
XSLT Magic Tricks
with
DITA and FrameMaker
Eliot Kimber
Contrext
Adobe DITA World 2017
About the Author
• Independent consultant focusing on DITA
analysis, design, and implementation
• Doing SGML and XML for cough 30 years cough
• Founding member of the DITA Technical
Committee
• Founding member of the XML Working Group
• Co-editor of HyTime standard (ISO/IEC 10744)
• Primary developer and founder of the DITA for
Publishers project
• Author of DITA for Practitioners, Vol 1 (XML
Press)
10/12/2017 Adobe DITA World 2
Agenda
• XSLT and FrameMaker
• XSLT Basics
• Configuring Your Structure
Application
• Magic Tricks
• Resources
10/12/2017 Adobe DITA World 3
XSLT AND FRAMEMAKER
10/12/2017 Adobe DITA World 4
What is XSLT?
• “XML Style Sheet Language
Transformations”
• Standard programming language for
manipulating XML documents
10/12/2017 Adobe DITA World 5
Why is XSLT Interesting?
• Makes it easy to make small changes
• Makes it possible to do big changes
• Mature standard with lots of support
in tools
• Same transform can be used in many
environments
10/12/2017 Adobe DITA World 6
What Does XSLT Do?
• Takes as input one or more XML
documents
• Produces as output any of:
– One or more XML documents
– Text data of any kind
– JSON (XSLT 3)
10/12/2017 Adobe DITA World 7
Transforms
• XSLT programs are “transforms”:
– One or more XML documents in
– One or more XML documents (or other
things) out
• Uses XML syntax:
<xsl:stylesheet>
<xsl:template …>
…
</xsl:template>
</xsl:stylesheet>
10/12/2017 Adobe DITA World 8
XSLT in FrameMaker
• Configured as part of structure
applications or associated with a
specific document
• Can apply XSLT transforms on
document open and document save
10/12/2017 Adobe DITA World 9
Which XSLT Engine?
• Can use Saxon or Xalan XSLT engine
• Use Saxon: Supports XSLT 2 and
newer
• Saxon is the default
• Can use a newer version or licensed
version of Saxon if desired
10/12/2017 Adobe DITA World 10
Why Use XSLT in FrameMaker
10/12/2017 Adobe DITA World 11
Alternative to Read/Write
Rules
• XSLT applied before read rules and
after write rules
• Can make it easier to adjust aspects
of the XML on import and export
10/12/2017 Adobe DITA World 12
Generate Additional Outputs
• Use XSLT on export to generate
additional outputs
– HTML files
– Reports
– Etc.
• Alternative to using DITA Open
Toolkit or FrameMaker-provided
features
10/12/2017 Adobe DITA World 13
Adjust XML
• Move elements around
• Add elements or attributes needed by
FrameMaker
• Group and sort elements (e.g., glossary
terms)
• Add index entries based on markup
• Adjust text details
• Control line breaking in examples
– Add zero-width-spaces
– Add non-breaking spaces
• Etc.
10/12/2017 Adobe DITA World 14
Validate Editorial and
Business Rules
• Check things not checkable with DTDs
or EDDs
– Rules for content
– Co-occurrence rules (e.g., “if A is present
then B must have attribute @foo”)
• Check rules not defined in the DTD or
EDD that reflect local usage:
– Require elements not required by DTD
– Require elements in a specific order
• Check rules for IDs, use of keys, etc.
10/12/2017 Adobe DITA World 15
Generalize on
Import/Specialize on Export
• Enable use of specialized content
with generic DITA FrameMaker
application
• “Generalization”: Transforming
specialized elements into one of their
ancestors
• Generalization is always reversable
10/12/2017 Adobe DITA World 16
Generalization Example
• Source element:
<mysection
class="- topic/section my-d/mysection ”
>
• Generalized:
<section
class="- topic/section my-d/mysection ”
>
• @class attribute retains original
specialization details
10/12/2017 Adobe DITA World 17
How Do I Do It?
10/12/2017 Adobe DITA World 18
Setting Up Structure
Applications
• From Structured Application Designer
go to “Advanced settings”
• Specify the XSLT transforms to use for
preprocessing (before read rules) or
postprocessing (after write rules)
• Or set up a transformations XML file
and refer to that from the structure
application
• See e.g.,
StructurexmlDITA_1.3apptechnical
ContentxsltDitaTransformations.xml
10/12/2017 Adobe DITA World 19
Pre- and Post-Processing
Configuration
10/12/2017 Adobe DITA World 20
XSLT BASICS
10/12/2017 Adobe DITA World 21
Style Sheets
• Style sheet document root:
<xsl:stylesheet
xmlns:xsl=http://www.w3.org/1999/XSL/Transform
xmlns:xs=http://www.w3.org/2001/XMLSchema
exclude-result-prefixes="xs”
version="2.0">
… {templates go here}
</xsl:stylesheet>
10/12/2017 Adobe DITA World 22
Templates
• Templates apply rules to elements
that match:
<xsl:template match="body/p">
…
</xsl:template>
• Literal result elements:
<xsl:template match="body/p">
<new-p someatt="value">
<xsl:apply-templates/>
</new-p>
</xsl:template>
10/12/2017 Adobe DITA World 23
Nodes and Templates
• XSLT treats XML documents as trees of
nodes:
– Elements
– Attributes
– Text nodes
• Input document is processed as a tree
starting with the document root node
• Templates are “applied” to nodes
• The first template that matches a node
handles it
10/12/2017 Adobe DITA World 24
Match Templates and Context
• Templates use XPath expressions to
match elements (and other types of
nodes):
<xsl:template match="body/p">
• XPath expression “body/p” matches
any <p> element that is a child of a
<body> element
10/12/2017 Adobe DITA World 25
Default Template
• Default template: matches any node
and applies templates to its child
nodes
10/12/2017 Adobe DITA World 26
Context Node
• The node that matches a template is
that template’s context node
• “.” in XPath expressions refers to the
context node:
<xsl:sequence select="."/>
10/12/2017 Adobe DITA World 27
Applying Templates to Nodes
• Within a template, process additional nodes
by applying templates to those nodes:
<xsl:template match="body/p">
<mypara>
<xsl:apply-templates/>
</mypara>
</xsl:template>
• The xsl:apply-templates instruction applies
templates to all child nodes of the current
node by default
• Can select specific nodes if you want
10/12/2017 Adobe DITA World 28
Selecting Specific Nodes
• Can select specific nodes with xsl:apply-templates:
<xsl:template match="fig">
<fig>
<xsl:apply-templates
select="(image|table|figgroup), title”
/>
</fig>
</xsl:template>
• Here the @select attribute says “process all <image>,
<table>, or <figgroup> elements then process any
<title> elements.”
• This example puts the <title> after the main
contents of the figure
10/12/2017 Adobe DITA World 29
Identity Transformations
• Identity transformations take a
document as input and produce the
equivalent document as output
• Form the base for most of what you’ll
want to do with FrameMaker
10/12/2017 Adobe DITA World 30
Typical Identity Transform
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="text()| @* | comment() |
processing-instruction()">
<xsl:sequence select="."/>
</xsl:template>
10/12/2017 Adobe DITA World 31
1
2
3
Identity Transform Part 1
• Matches the document root (“/”) and
applies templates to all the child nodes
of the root:
10/12/2017 Adobe DITA World 32
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
Identity Transform Part 2
• Matches any element node (“*”)
• The @priority attribute value of “-1” means
“make this template a lower priority than
any template with a default priority.
– Makes it easy to add templates for specific
elements without worrying about priority
10/12/2017 Adobe DITA World 33
<xsl:template match="*" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
Identity Transform Part 2
• Creates a copy of the element:
<xsl:copy>
…
</xsl:copy>
• Applies templates to all the attributes:
<xsl:apply-templates select="@*"/>
• Applies templates to all the child
nodes:
<xsl:apply-templates select="node()"/>
10/12/2017 Adobe DITA World 34
Identity Transform Part 3
• Handles nodes that can’t have children:
– Text nodes, attributes, comments, and
processing instructions
• Simply copies the input node to the
output:
<xsl:sequence select="."/>
10/12/2017 Adobe DITA World 35
<xsl:template
match="text()| @* | comment() |
processing-instruction()">
<xsl:sequence select="."/>
</xsl:template>
Identity Transform Part 3
• The xsl:sequence instruction simply
outputs the value of the @select
attribute
• Here “.” means “the current context
node”, which is whatever node matched
this template
10/12/2017 Adobe DITA World 36
<xsl:template
match="text()| @* | comment() |
processing-instruction()">
<xsl:sequence select="."/>
</xsl:template>
XSLT Modules
• Can organize style sheets into two or more files
• One file is always the top-level module
• Can “import” or “include” modules
• For simple transforms always use “import”
– Avoids complexities around template priority
– Last module imported has highest priority among
the imported modules
– Importing (top-level) module always has highest
priority
• Don’t put “catch all” templates in top-level
module
– Cannot be overridden by imported modules
10/12/2017 Adobe DITA World 37
Two-Module Identity
Transform
• Base module has base identity transform
• Top-level module has overrides
• Base module: identity.xsl
– Provides the generic identity transform templates
• Top-level module: imports identity.xsl:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:import href="identity.xsl"/>
<xsl:template match="fig">
...
</xsl:template>
</xsl:stylesheet>
• Call the top-level module from your structured
application
10/12/2017 Adobe DITA World 38
MAGIC TRICKS
10/12/2017 Adobe DITA World 39
Trick: Make Notes Into
Hazard Statements
• Find <note> elements with @type of
“caution”, “warning”, or “danger”
• Change them into
<hazardstatement> elements on
document open
10/12/2017 Adobe DITA World 40
Step 1: Implement Transform
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs" version="2.0">
<!-- Convert notes of type "warning", "caution", and "danger"
to hazard statements.
-->
<xsl:import href="../common/identity.xsl"/>
<xsl:output indent="yes"/>
<xsl:template
match="*[contains(@class, ' topic/note ')]
[@type = ('warning', 'caution', 'danger')]">
<hazardstatement>
<xsl:sequence select="@*"/>
<messagepanel>
<typeofhazard>[type of hazard]</typeofhazard>
<consequence><xsl:apply-templates/></consequence>
<howtoavoid>{how to avoid}</howtoavoid>
</messagepanel>
</hazardstatement>
</xsl:template>
</xsl:stylesheet>
10/12/2017 Adobe DITA World 41
Step 2: Add to Structure
Application
10/12/2017 Adobe DITA World 42
Step 3: Try It
10/12/2017 Adobe DITA World 43
Before:
After:
Trick: Move Figure Titles To
Bottom of Figure
• DITA content models put figure titles
at top of figure
• Typical print layout puts them at
bottom of figure
• Nice to have this in the editor
10/12/2017 Adobe DITA World 44
Step 1: Hack the DTDs
• Requires hacking DITA <fig> content model to allow
<title> at end of figure
• E.g., modify commonElements.mod in the FrameMaker
copy of the DITA DTDs:
<!-- LONG NAME:
Figure -->
<!ENTITY % fig.content
"((%title;)?,
(%desc;)?,
(%figgroup; |
%fig.cnt;)*,
((%title;)?,
(%desc)?)?)"
>
• No need to change the EDD unless you want structure view
to not flag figure content as invalid.
10/12/2017 Adobe DITA World 45
Step 2: Pair of Transforms
• Transform one: moves <title> and
<desc> to end of figures on open
– Preprocessing transform
• Transform two: moves <title> and
<desc> back to top of figures on save
– Postprocessing transform
• Both are based on identity transform
10/12/2017 Adobe DITA World 46
One Challenge: DOCTYPE
• Transform needs to set the DOCTYPE
declaration correctly, especially on save
• XSLT doesn’t allow dynamically setting
of main result file DOCTYPE values
• Two solutions:
– One top-level transform per topic type
– Use disable-output-escaping to construct
DOCTYPE declaration dynamically
• See built-in AdjustTableWidth.xsl for example
10/12/2017 Adobe DITA World 47
Step 3: Update Structure App
• For each topic type add
Preprocessing and Postprocessing
entries to XSLT Preferences settings
10/12/2017 Adobe DITA World 48
XSLT Preferences Sample
10/12/2017 Adobe DITA World 49
Step 4: Try It
10/12/2017 Adobe DITA World 50
Before: After:
Postprocessing Undoes
Preprocessing
• The moved title is only seen in the
Author view in FrameMaker
• The postprocessing transform is
applied on save
• Also applied when switching to XML
view
• No chance of getting invalid DITA
content outside of FrameMaker
10/12/2017 Adobe DITA World 51
RESOURCES
10/12/2017 Adobe DITA World 52
Online XSLT Resources
• XSLT 2 specification:
http://www.w3.org/TR/xslt20/
• XPath specification:
http://www.w3.org/TR/xpath20/
• XQuery and Xpath 2 functions and operators:
http://www.w3.org/TR/xpath-functions/
• Ken Holman’s XSLT book:
http://www.cranesoftwrights.com/training/
index.htm#ptux
• XSL mailing list (searchable with MarkMail):
http://mulberrytech.com/xsl/xsl-list/index.html
10/12/2017 Adobe DITA World 53
Books
• Mike Kay’s XSLT 2.0 and XPath 2.0
Programmer’s Reference:
http://www.wrox.com/WileyCDA/WroxT
itle/XSLT-2-0-and-XPath-2-0-
Programmer-s-Reference-4th-
Edition.productCd-0470192747.html
– Authoritative reference to the standard.
Not a beginner’s guide
• Search Amazon for “XSLT”. Look for
books that reflect XSLT 2 or later
10/12/2017 Adobe DITA World 54
Questions?
10/12/2017 Adobe DITA World 55

More Related Content

PDF
Azure Cognitive Services for Developers
PDF
DITA Metadata
PDF
Domain Driven Design (Ultra) Distilled
PPTX
Personal Voice Assistant using python.pptx
PDF
Linked (open) data: het met elkaar verbinden van kennis en organisaties
PPTX
Microsoft Azure - Introduction
PDF
APIsecure 2023 - API orchestration: to build resilient applications, Cherish ...
PDF
Css Preprocessors
Azure Cognitive Services for Developers
DITA Metadata
Domain Driven Design (Ultra) Distilled
Personal Voice Assistant using python.pptx
Linked (open) data: het met elkaar verbinden van kennis en organisaties
Microsoft Azure - Introduction
APIsecure 2023 - API orchestration: to build resilient applications, Cherish ...
Css Preprocessors

What's hot (20)

PDF
ROBLOX for Parents
PDF
Dynamic website quotation
PPTX
Building stateful serverless orchestrations with Azure Durable Azure Function...
PPTX
Introduction to DDD
PDF
DITA and Metadata on an Enterprise Scale
PDF
Basic Introduction to Web Development
PDF
Front end development best practices
PPT
Domain Driven Design (DDD)
PDF
Fast DDS Hello World in Windows
PDF
IBM MobileFirst Reference Architecture 1512 v3 2015
PDF
Taxonomies for Users
PPTX
An introduction to Microsoft Bot Framework
PDF
Profissão Front-end
PDF
DevEx | there’s no place like k3s
PDF
Docker cheat-sheet
PPTX
Introduction to microservices
PDF
Svelte the future of frontend development
PPTX
Utilise Google Workspace LW.pptx
PPTX
Domain-Driven Design
ROBLOX for Parents
Dynamic website quotation
Building stateful serverless orchestrations with Azure Durable Azure Function...
Introduction to DDD
DITA and Metadata on an Enterprise Scale
Basic Introduction to Web Development
Front end development best practices
Domain Driven Design (DDD)
Fast DDS Hello World in Windows
IBM MobileFirst Reference Architecture 1512 v3 2015
Taxonomies for Users
An introduction to Microsoft Bot Framework
Profissão Front-end
DevEx | there’s no place like k3s
Docker cheat-sheet
Introduction to microservices
Svelte the future of frontend development
Utilise Google Workspace LW.pptx
Domain-Driven Design
Ad

Similar to XSLT Magic Tricks with DITA and FrameMaker (20)

PDF
XMetaL DITA Workshop
PPT
Authoring and Publishing with XMetaL and DITA
PPTX
The Mystical Principles of XSLT: Enlightenment through Software Visualization
PPTX
Overview of XSL, XPath and XSL-FO
PPT
Xslt by asfak mahamud
PDF
Learning Xslt A Handson Introduction To Xslt And Xpath 1st Edition Michael Ja...
PPT
Learning XSLT
PPTX
Xml data transformation
PPT
PDF
26xslt
PPTX
Coming Up to Speed with XML Authoring in Adobe FrameMaker
PDF
XSLT and XPath - without the pain!
DOC
DOC
PPTX
DITA Quick Start Webinar Series: Getting Started with the DITA Open Toolkit
PPT
PPTX
Overview of the DITA Open Toolkit
PPTX
DSpace 4.2 XMLUI Theming
PDF
Notes from the Library Juice Academy courses on XPath, XSLT, and XQuery: Univ...
PDF
php
XMetaL DITA Workshop
Authoring and Publishing with XMetaL and DITA
The Mystical Principles of XSLT: Enlightenment through Software Visualization
Overview of XSL, XPath and XSL-FO
Xslt by asfak mahamud
Learning Xslt A Handson Introduction To Xslt And Xpath 1st Edition Michael Ja...
Learning XSLT
Xml data transformation
26xslt
Coming Up to Speed with XML Authoring in Adobe FrameMaker
XSLT and XPath - without the pain!
DITA Quick Start Webinar Series: Getting Started with the DITA Open Toolkit
Overview of the DITA Open Toolkit
DSpace 4.2 XMLUI Theming
Notes from the Library Juice Academy courses on XPath, XSLT, and XQuery: Univ...
php
Ad

More from Contrext Solutions (20)

PPTX
Stupid DITA Tricks: After-The-Fact Specialization: Treating Aircraft Manuals ...
PPTX
Loose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
PPTX
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
PPTX
Twisted XSL Tricks: Column Switching for FOP
PDF
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
PPTX
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key References
PPTX
Content Management on Zero Budget: DITA for Small Teams
PPTX
Using CSS Paging to Render DITA Documents
PPTX
Locale-Aware Sorting and Text Handling in the Open Toolkit
PPTX
DITA for Small Teams Workshop (Tekom 2017)
PPTX
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
PPTX
FrameMaker and the DITA Open Toolkit
PPTX
DITA Reuse Challenges and Response
PPTX
RELAX NG and DITA: An Almost Perfect Match
PPTX
Managing Multiple Open Toolkit Configurations Using git Lightning Talk
PPTX
DITA OT Day 2015 Lightning Talk On The DITA Community Project
PPTX
Why Is DITA So Hard?
PPTX
They Worked Before, What Happened? Understanding DITA Cross-Book Links
PPTX
No Ki Magic: Managing Complex DITA Hyperdocuments
PPTX
Poster: Cross-Document Linking in DITA
Stupid DITA Tricks: After-The-Fact Specialization: Treating Aircraft Manuals ...
Loose Leaf Publishing Using Antenna House Formatter and CSS for Pagination
Definition of the DITA Glossary: Or How to Get Some Cool Glossary Tools for Free
Twisted XSL Tricks: Column Switching for FOP
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
Ki, Qi, Key: The Way of DITA Harmony With Keys and Key References
Content Management on Zero Budget: DITA for Small Teams
Using CSS Paging to Render DITA Documents
Locale-Aware Sorting and Text Handling in the Open Toolkit
DITA for Small Teams Workshop (Tekom 2017)
Can I Have a Word: Managing Shared Glossaries and References to Terms With DITA
FrameMaker and the DITA Open Toolkit
DITA Reuse Challenges and Response
RELAX NG and DITA: An Almost Perfect Match
Managing Multiple Open Toolkit Configurations Using git Lightning Talk
DITA OT Day 2015 Lightning Talk On The DITA Community Project
Why Is DITA So Hard?
They Worked Before, What Happened? Understanding DITA Cross-Book Links
No Ki Magic: Managing Complex DITA Hyperdocuments
Poster: Cross-Document Linking in DITA

Recently uploaded (20)

PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
top salesforce developer skills in 2025.pdf
PDF
Nekopoi APK 2025 free lastest update
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PPTX
L1 - Introduction to python Backend.pptx
PPTX
ai tools demonstartion for schools and inter college
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Essential Infomation Tech presentation.pptx
PDF
medical staffing services at VALiNTRY
Odoo POS Development Services by CandidRoot Solutions
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
top salesforce developer skills in 2025.pdf
Nekopoi APK 2025 free lastest update
Upgrade and Innovation Strategies for SAP ERP Customers
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
How Creative Agencies Leverage Project Management Software.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf
L1 - Introduction to python Backend.pptx
ai tools demonstartion for schools and inter college
How to Choose the Right IT Partner for Your Business in Malaysia
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PTS Company Brochure 2025 (1).pdf.......
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Wondershare Filmora 15 Crack With Activation Key [2025
Essential Infomation Tech presentation.pptx
medical staffing services at VALiNTRY

XSLT Magic Tricks with DITA and FrameMaker

  • 1. XSLT Magic Tricks with DITA and FrameMaker Eliot Kimber Contrext Adobe DITA World 2017
  • 2. About the Author • Independent consultant focusing on DITA analysis, design, and implementation • Doing SGML and XML for cough 30 years cough • Founding member of the DITA Technical Committee • Founding member of the XML Working Group • Co-editor of HyTime standard (ISO/IEC 10744) • Primary developer and founder of the DITA for Publishers project • Author of DITA for Practitioners, Vol 1 (XML Press) 10/12/2017 Adobe DITA World 2
  • 3. Agenda • XSLT and FrameMaker • XSLT Basics • Configuring Your Structure Application • Magic Tricks • Resources 10/12/2017 Adobe DITA World 3
  • 4. XSLT AND FRAMEMAKER 10/12/2017 Adobe DITA World 4
  • 5. What is XSLT? • “XML Style Sheet Language Transformations” • Standard programming language for manipulating XML documents 10/12/2017 Adobe DITA World 5
  • 6. Why is XSLT Interesting? • Makes it easy to make small changes • Makes it possible to do big changes • Mature standard with lots of support in tools • Same transform can be used in many environments 10/12/2017 Adobe DITA World 6
  • 7. What Does XSLT Do? • Takes as input one or more XML documents • Produces as output any of: – One or more XML documents – Text data of any kind – JSON (XSLT 3) 10/12/2017 Adobe DITA World 7
  • 8. Transforms • XSLT programs are “transforms”: – One or more XML documents in – One or more XML documents (or other things) out • Uses XML syntax: <xsl:stylesheet> <xsl:template …> … </xsl:template> </xsl:stylesheet> 10/12/2017 Adobe DITA World 8
  • 9. XSLT in FrameMaker • Configured as part of structure applications or associated with a specific document • Can apply XSLT transforms on document open and document save 10/12/2017 Adobe DITA World 9
  • 10. Which XSLT Engine? • Can use Saxon or Xalan XSLT engine • Use Saxon: Supports XSLT 2 and newer • Saxon is the default • Can use a newer version or licensed version of Saxon if desired 10/12/2017 Adobe DITA World 10
  • 11. Why Use XSLT in FrameMaker 10/12/2017 Adobe DITA World 11
  • 12. Alternative to Read/Write Rules • XSLT applied before read rules and after write rules • Can make it easier to adjust aspects of the XML on import and export 10/12/2017 Adobe DITA World 12
  • 13. Generate Additional Outputs • Use XSLT on export to generate additional outputs – HTML files – Reports – Etc. • Alternative to using DITA Open Toolkit or FrameMaker-provided features 10/12/2017 Adobe DITA World 13
  • 14. Adjust XML • Move elements around • Add elements or attributes needed by FrameMaker • Group and sort elements (e.g., glossary terms) • Add index entries based on markup • Adjust text details • Control line breaking in examples – Add zero-width-spaces – Add non-breaking spaces • Etc. 10/12/2017 Adobe DITA World 14
  • 15. Validate Editorial and Business Rules • Check things not checkable with DTDs or EDDs – Rules for content – Co-occurrence rules (e.g., “if A is present then B must have attribute @foo”) • Check rules not defined in the DTD or EDD that reflect local usage: – Require elements not required by DTD – Require elements in a specific order • Check rules for IDs, use of keys, etc. 10/12/2017 Adobe DITA World 15
  • 16. Generalize on Import/Specialize on Export • Enable use of specialized content with generic DITA FrameMaker application • “Generalization”: Transforming specialized elements into one of their ancestors • Generalization is always reversable 10/12/2017 Adobe DITA World 16
  • 17. Generalization Example • Source element: <mysection class="- topic/section my-d/mysection ” > • Generalized: <section class="- topic/section my-d/mysection ” > • @class attribute retains original specialization details 10/12/2017 Adobe DITA World 17
  • 18. How Do I Do It? 10/12/2017 Adobe DITA World 18
  • 19. Setting Up Structure Applications • From Structured Application Designer go to “Advanced settings” • Specify the XSLT transforms to use for preprocessing (before read rules) or postprocessing (after write rules) • Or set up a transformations XML file and refer to that from the structure application • See e.g., StructurexmlDITA_1.3apptechnical ContentxsltDitaTransformations.xml 10/12/2017 Adobe DITA World 19
  • 22. Style Sheets • Style sheet document root: <xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform xmlns:xs=http://www.w3.org/2001/XMLSchema exclude-result-prefixes="xs” version="2.0"> … {templates go here} </xsl:stylesheet> 10/12/2017 Adobe DITA World 22
  • 23. Templates • Templates apply rules to elements that match: <xsl:template match="body/p"> … </xsl:template> • Literal result elements: <xsl:template match="body/p"> <new-p someatt="value"> <xsl:apply-templates/> </new-p> </xsl:template> 10/12/2017 Adobe DITA World 23
  • 24. Nodes and Templates • XSLT treats XML documents as trees of nodes: – Elements – Attributes – Text nodes • Input document is processed as a tree starting with the document root node • Templates are “applied” to nodes • The first template that matches a node handles it 10/12/2017 Adobe DITA World 24
  • 25. Match Templates and Context • Templates use XPath expressions to match elements (and other types of nodes): <xsl:template match="body/p"> • XPath expression “body/p” matches any <p> element that is a child of a <body> element 10/12/2017 Adobe DITA World 25
  • 26. Default Template • Default template: matches any node and applies templates to its child nodes 10/12/2017 Adobe DITA World 26
  • 27. Context Node • The node that matches a template is that template’s context node • “.” in XPath expressions refers to the context node: <xsl:sequence select="."/> 10/12/2017 Adobe DITA World 27
  • 28. Applying Templates to Nodes • Within a template, process additional nodes by applying templates to those nodes: <xsl:template match="body/p"> <mypara> <xsl:apply-templates/> </mypara> </xsl:template> • The xsl:apply-templates instruction applies templates to all child nodes of the current node by default • Can select specific nodes if you want 10/12/2017 Adobe DITA World 28
  • 29. Selecting Specific Nodes • Can select specific nodes with xsl:apply-templates: <xsl:template match="fig"> <fig> <xsl:apply-templates select="(image|table|figgroup), title” /> </fig> </xsl:template> • Here the @select attribute says “process all <image>, <table>, or <figgroup> elements then process any <title> elements.” • This example puts the <title> after the main contents of the figure 10/12/2017 Adobe DITA World 29
  • 30. Identity Transformations • Identity transformations take a document as input and produce the equivalent document as output • Form the base for most of what you’ll want to do with FrameMaker 10/12/2017 Adobe DITA World 30
  • 31. Typical Identity Transform <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="*" priority="-1"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <xsl:template match="text()| @* | comment() | processing-instruction()"> <xsl:sequence select="."/> </xsl:template> 10/12/2017 Adobe DITA World 31 1 2 3
  • 32. Identity Transform Part 1 • Matches the document root (“/”) and applies templates to all the child nodes of the root: 10/12/2017 Adobe DITA World 32 <xsl:template match="/"> <xsl:apply-templates/> </xsl:template>
  • 33. Identity Transform Part 2 • Matches any element node (“*”) • The @priority attribute value of “-1” means “make this template a lower priority than any template with a default priority. – Makes it easy to add templates for specific elements without worrying about priority 10/12/2017 Adobe DITA World 33 <xsl:template match="*" priority="-1"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template>
  • 34. Identity Transform Part 2 • Creates a copy of the element: <xsl:copy> … </xsl:copy> • Applies templates to all the attributes: <xsl:apply-templates select="@*"/> • Applies templates to all the child nodes: <xsl:apply-templates select="node()"/> 10/12/2017 Adobe DITA World 34
  • 35. Identity Transform Part 3 • Handles nodes that can’t have children: – Text nodes, attributes, comments, and processing instructions • Simply copies the input node to the output: <xsl:sequence select="."/> 10/12/2017 Adobe DITA World 35 <xsl:template match="text()| @* | comment() | processing-instruction()"> <xsl:sequence select="."/> </xsl:template>
  • 36. Identity Transform Part 3 • The xsl:sequence instruction simply outputs the value of the @select attribute • Here “.” means “the current context node”, which is whatever node matched this template 10/12/2017 Adobe DITA World 36 <xsl:template match="text()| @* | comment() | processing-instruction()"> <xsl:sequence select="."/> </xsl:template>
  • 37. XSLT Modules • Can organize style sheets into two or more files • One file is always the top-level module • Can “import” or “include” modules • For simple transforms always use “import” – Avoids complexities around template priority – Last module imported has highest priority among the imported modules – Importing (top-level) module always has highest priority • Don’t put “catch all” templates in top-level module – Cannot be overridden by imported modules 10/12/2017 Adobe DITA World 37
  • 38. Two-Module Identity Transform • Base module has base identity transform • Top-level module has overrides • Base module: identity.xsl – Provides the generic identity transform templates • Top-level module: imports identity.xsl: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:import href="identity.xsl"/> <xsl:template match="fig"> ... </xsl:template> </xsl:stylesheet> • Call the top-level module from your structured application 10/12/2017 Adobe DITA World 38
  • 40. Trick: Make Notes Into Hazard Statements • Find <note> elements with @type of “caution”, “warning”, or “danger” • Change them into <hazardstatement> elements on document open 10/12/2017 Adobe DITA World 40
  • 41. Step 1: Implement Transform <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <!-- Convert notes of type "warning", "caution", and "danger" to hazard statements. --> <xsl:import href="../common/identity.xsl"/> <xsl:output indent="yes"/> <xsl:template match="*[contains(@class, ' topic/note ')] [@type = ('warning', 'caution', 'danger')]"> <hazardstatement> <xsl:sequence select="@*"/> <messagepanel> <typeofhazard>[type of hazard]</typeofhazard> <consequence><xsl:apply-templates/></consequence> <howtoavoid>{how to avoid}</howtoavoid> </messagepanel> </hazardstatement> </xsl:template> </xsl:stylesheet> 10/12/2017 Adobe DITA World 41
  • 42. Step 2: Add to Structure Application 10/12/2017 Adobe DITA World 42
  • 43. Step 3: Try It 10/12/2017 Adobe DITA World 43 Before: After:
  • 44. Trick: Move Figure Titles To Bottom of Figure • DITA content models put figure titles at top of figure • Typical print layout puts them at bottom of figure • Nice to have this in the editor 10/12/2017 Adobe DITA World 44
  • 45. Step 1: Hack the DTDs • Requires hacking DITA <fig> content model to allow <title> at end of figure • E.g., modify commonElements.mod in the FrameMaker copy of the DITA DTDs: <!-- LONG NAME: Figure --> <!ENTITY % fig.content "((%title;)?, (%desc;)?, (%figgroup; | %fig.cnt;)*, ((%title;)?, (%desc)?)?)" > • No need to change the EDD unless you want structure view to not flag figure content as invalid. 10/12/2017 Adobe DITA World 45
  • 46. Step 2: Pair of Transforms • Transform one: moves <title> and <desc> to end of figures on open – Preprocessing transform • Transform two: moves <title> and <desc> back to top of figures on save – Postprocessing transform • Both are based on identity transform 10/12/2017 Adobe DITA World 46
  • 47. One Challenge: DOCTYPE • Transform needs to set the DOCTYPE declaration correctly, especially on save • XSLT doesn’t allow dynamically setting of main result file DOCTYPE values • Two solutions: – One top-level transform per topic type – Use disable-output-escaping to construct DOCTYPE declaration dynamically • See built-in AdjustTableWidth.xsl for example 10/12/2017 Adobe DITA World 47
  • 48. Step 3: Update Structure App • For each topic type add Preprocessing and Postprocessing entries to XSLT Preferences settings 10/12/2017 Adobe DITA World 48
  • 49. XSLT Preferences Sample 10/12/2017 Adobe DITA World 49
  • 50. Step 4: Try It 10/12/2017 Adobe DITA World 50 Before: After:
  • 51. Postprocessing Undoes Preprocessing • The moved title is only seen in the Author view in FrameMaker • The postprocessing transform is applied on save • Also applied when switching to XML view • No chance of getting invalid DITA content outside of FrameMaker 10/12/2017 Adobe DITA World 51
  • 53. Online XSLT Resources • XSLT 2 specification: http://www.w3.org/TR/xslt20/ • XPath specification: http://www.w3.org/TR/xpath20/ • XQuery and Xpath 2 functions and operators: http://www.w3.org/TR/xpath-functions/ • Ken Holman’s XSLT book: http://www.cranesoftwrights.com/training/ index.htm#ptux • XSL mailing list (searchable with MarkMail): http://mulberrytech.com/xsl/xsl-list/index.html 10/12/2017 Adobe DITA World 53
  • 54. Books • Mike Kay’s XSLT 2.0 and XPath 2.0 Programmer’s Reference: http://www.wrox.com/WileyCDA/WroxT itle/XSLT-2-0-and-XPath-2-0- Programmer-s-Reference-4th- Edition.productCd-0470192747.html – Authoritative reference to the standard. Not a beginner’s guide • Search Amazon for “XSLT”. Look for books that reflect XSLT 2 or later 10/12/2017 Adobe DITA World 54