xslt magic tricks with dita and framemaker

55
XSLT Magic Tricks with DITA and FrameMaker Eliot Kimber Contrext Adobe DITA World 2017

Upload: contrext-solutions

Post on 28-Jan-2018

76 views

Category:

Software


2 download

TRANSCRIPT

Page 1: XSLT Magic Tricks with DITA and FrameMaker

XSLT Magic Tricks with

DITA and FrameMaker

Eliot KimberContrext

Adobe DITA World 2017

Page 2: XSLT Magic Tricks with DITA and FrameMaker

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

Page 3: XSLT Magic Tricks with DITA and FrameMaker

Agenda

• XSLT and FrameMaker

• XSLT Basics

• Configuring Your Structure Application

• Magic Tricks

• Resources

10/12/2017 Adobe DITA World 3

Page 4: XSLT Magic Tricks with DITA and FrameMaker

XSLT AND FRAMEMAKER

10/12/2017 Adobe DITA World 4

Page 5: XSLT Magic Tricks with DITA and FrameMaker

What is XSLT?

• “XML Style Sheet Language Transformations”

• Standard programming language for manipulating XML documents

10/12/2017 Adobe DITA World 5

Page 6: XSLT Magic Tricks with DITA and FrameMaker

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

Page 7: XSLT Magic Tricks with DITA and FrameMaker

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

Page 8: XSLT Magic Tricks with DITA and FrameMaker

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

Page 9: XSLT Magic Tricks with DITA and FrameMaker

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

Page 10: XSLT Magic Tricks with DITA and FrameMaker

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

Page 11: XSLT Magic Tricks with DITA and FrameMaker

Why Use XSLT in FrameMaker

10/12/2017 Adobe DITA World 11

Page 12: XSLT Magic Tricks with DITA and FrameMaker

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

Page 13: XSLT Magic Tricks with DITA and FrameMaker

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

Page 14: XSLT Magic Tricks with DITA and FrameMaker

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

Page 15: XSLT Magic Tricks with DITA and FrameMaker

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

Page 16: XSLT Magic Tricks with DITA and FrameMaker

Generalize on Import/Specialize on Export

• Enable use of specialized content with generic DITA FrameMakerapplication

• “Generalization”: Transforming specialized elements into one of their ancestors

• Generalization is always reversable

10/12/2017 Adobe DITA World 16

Page 17: XSLT Magic Tricks with DITA and FrameMaker

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

Page 18: XSLT Magic Tricks with DITA and FrameMaker

How Do I Do It?

10/12/2017 Adobe DITA World 18

Page 19: XSLT Magic Tricks with DITA and FrameMaker

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., Structure\xml\DITA_1.3\app\technicalContent\xslt\DitaTransformations.xml

10/12/2017 Adobe DITA World 19

Page 20: XSLT Magic Tricks with DITA and FrameMaker

Pre- and Post-Processing Configuration

10/12/2017 Adobe DITA World 20

Page 21: XSLT Magic Tricks with DITA and FrameMaker

XSLT BASICS

10/12/2017 Adobe DITA World 21

Page 22: XSLT Magic Tricks with DITA and FrameMaker

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

Page 23: XSLT Magic Tricks with DITA and FrameMaker

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

Page 24: XSLT Magic Tricks with DITA and FrameMaker

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

Page 25: XSLT Magic Tricks with DITA and FrameMaker

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

Page 26: XSLT Magic Tricks with DITA and FrameMaker

Default Template

• Default template: matches any node and applies templates to its child nodes

10/12/2017 Adobe DITA World 26

Page 27: XSLT Magic Tricks with DITA and FrameMaker

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

Page 28: XSLT Magic Tricks with DITA and FrameMaker

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

Page 29: XSLT Magic Tricks with DITA and FrameMaker

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

Page 30: XSLT Magic Tricks with DITA and FrameMaker

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

Page 31: XSLT Magic Tricks with DITA and FrameMaker

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

Page 32: XSLT Magic Tricks with DITA and FrameMaker

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>

Page 33: XSLT Magic Tricks with DITA and FrameMaker

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>

Page 34: XSLT Magic Tricks with DITA and FrameMaker

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

Page 35: XSLT Magic Tricks with DITA and FrameMaker

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>

Page 36: XSLT Magic Tricks with DITA and FrameMaker

Identity Transform Part 3

• The xsl:sequence instruction simply outputs the value of the @selectattribute

• 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>

Page 37: XSLT Magic Tricks with DITA and FrameMaker

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

Page 38: XSLT Magic Tricks with DITA and FrameMaker

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

Page 39: XSLT Magic Tricks with DITA and FrameMaker

MAGIC TRICKS

10/12/2017 Adobe DITA World 39

Page 40: XSLT Magic Tricks with DITA and FrameMaker

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

Page 41: XSLT Magic Tricks with DITA and FrameMaker

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:templatematch="*[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

Page 42: XSLT Magic Tricks with DITA and FrameMaker

Step 2: Add to Structure Application

10/12/2017 Adobe DITA World 42

Page 43: XSLT Magic Tricks with DITA and FrameMaker

Step 3: Try It

10/12/2017 Adobe DITA World 43

Before:

After:

Page 44: XSLT Magic Tricks with DITA and FrameMaker

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

Page 45: XSLT Magic Tricks with DITA and FrameMaker

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 FrameMakercopy 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

Page 46: XSLT Magic Tricks with DITA and FrameMaker

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

Page 47: XSLT Magic Tricks with DITA and FrameMaker

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

Page 48: XSLT Magic Tricks with DITA and FrameMaker

Step 3: Update Structure App

• For each topic type add Preprocessing and Postprocessingentries to XSLT Preferences settings

10/12/2017 Adobe DITA World 48

Page 49: XSLT Magic Tricks with DITA and FrameMaker

XSLT Preferences Sample

10/12/2017 Adobe DITA World 49

Page 50: XSLT Magic Tricks with DITA and FrameMaker

Step 4: Try It

10/12/2017 Adobe DITA World 50

Before: After:

Page 51: XSLT Magic Tricks with DITA and FrameMaker

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

Page 52: XSLT Magic Tricks with DITA and FrameMaker

RESOURCES

10/12/2017 Adobe DITA World 52

Page 53: XSLT Magic Tricks with DITA and FrameMaker

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

Page 54: XSLT Magic Tricks with DITA and FrameMaker

Books

• Mike Kay’s XSLT 2.0 and XPath 2.0 Programmer’s Reference: http://www.wrox.com/WileyCDA/WroxTitle/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

Page 55: XSLT Magic Tricks with DITA and FrameMaker

Questions?

10/12/2017 Adobe DITA World 55