XML Productivity Features

Transcription

XML Productivity Features
XML Productivity Features
Technical Note #10044
Version InDesign CS
Feb 2004
ADOBE SYSTEMS INCORPORATED
Corporate Headquarters
345 Park Avenue
San Jose, CA 95110-2704
(408) 536-6000
Copyright 2004 Adobe Systems Incorporated. All rights reserved.
The information in this document is furnished for informational use only, is subject to change without notice, and should not be construed as a
commitment by Adobe Systems Incorporated. Adobe Systems Incorporated assumes no responsibility or liability for any errors or inaccuracies that
may appear in this document. The software described in this document is furnished under license and may only be used or copied in accordance with
the terms of such license.
Adobe, Adobe After Effects, Adobe InDesign, Adobe PhotoDeluxe, Adobe Premiere, Adobe Photoshop, Adobe Illustrator, Adobe Type Manager,
ATM and PostScript are trademarks of Adobe Systems Incorporated that may be registered in certain jurisdictions. Macintosh and Apple are
registered trademarks, and Mac OS is a trademark of Apple Computer, Inc. Microsoft, Windows, Windows 95, Windows 98, and Windows NT are
registered trademarks of Microsoft Corporation. All other products or name brands are trademarks of their respective holders..
Rev #
Date
Author
Comments
0.1
Nov 2003
Ian Paterson
New outline for CS features; re-write of the
2.0 tech-note.
0.2
Dec 2003
Ian Paterson
Refactored to new structure based on pattern
as follows; feature-description, design, usecases per feature area
0.3
Jan 2003
Ian Paterson
Tidied up prior to review and re-factored
slightly.
0.4
Jan 2004
Ian Paterson
Rolled in Rodney Cook’s review comments
0.5
Jan 2004
Ian Paterson
Integrated review comments from Ken
Sadahiro.
Contents
Chapter
XML Productivity Features . . . . . . . . . . . . . . . . . . . . . . . 7
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Terminology and definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Programming and the application object model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Modelling the domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Features In InDesign CS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Character styles mapped to tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Support for XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Validation against DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Support for table headers and footers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Support for comments and processing instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Customising the SAX parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Walkthrough: importing XML into a template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Importing graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Importing text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Key design concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Logical structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Key associations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Document element and root element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Importing and exporting XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Suites and utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Import and export . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Importing XML data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Exporting XML data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Importing a table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Exporting a table to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Tags and the tag-list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Loading tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Saving tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3
Contents
Creating, updating and deleting tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Mappings between tags and run-styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Creating and modifying the mapping from tag to run-style . . . . . . . . . . . . . . . . . . . . . . 49
Creating and modifying the mapping from run-style to tag . . . . . . . . . . . . . . . . . . . . . . 50
Applying a mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Changing logical structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Creating, updating and deleting elements and attributes . . . . . . . . . . . . . . . . . . . . . . . 60
Tagging text and graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
DTD and validation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Associate DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Validate against DTD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Processing instructions and comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Adding comments and processing instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
User interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Visibility of the structure-view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Appearance of the structure-view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
XSL support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Feature description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Transforming imported XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Walkthrough: transforming imported XML with XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Extension points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Custom suite for the structure-view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
XSL Enabler. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Custom SAX Content handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Custom tag service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Custom SAX entity resolver. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Frequently asked questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
What is the difference between logical structure and the native document model? . . . . . . . 78
4
Feb 2004
XML Productivity Features
Contents
How do I make a selection in the structure view? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
How do I create, update or delete elements in the logical structure? . . . . . . . . . . . . . . . . 79
How can I read in some arbitrary XML content? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
How do I validate an XML document from within the applications? . . . . . . . . . . . . . . . . . 80
How do I change the XML import options?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Summary and conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Native document model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Backing store. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Root backing store and notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Low-level command notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Entities supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Assets from XSLT example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
XML Productivity Features
Feb 2004
5
Contents
6
Feb 2004
XML Productivity Features
XML Productivity Features
Overview
XML Productivity Features
Overview
This document provides an overview of the design of the XML features available in InDesign
CS and describes how to work with the XML-related API as a client of the API. It also
introduces some XML-related extension points that allow you to customize the behaviour of
the applications.
The feature highlights for this release include support for validation against a document type
definition (DTD) and support for applying an XSL style sheet during import to transform
between XML grammars.
Terminology and definitions
This section defines terms used within this document alone. Some fundamental terms used in
the API (e.g. boss class, add-in) are defined here to ensure that the meaning of these terms for
the reader of this document is consistent the one intended by the author.
•
add-in; an interface that decorates an existing boss class. It is defined in the resource
language ODFRez (Object Definition Format resource language).
•
API; InDesign CS Application Programming Interface.
•
API documentation; refers to the API documentation in the SDK in a browseable format
(Windows Compiled Help/ HTML) generated from doc++ style comments in the source
code and information from FR files and the object model.
•
application; InDesign CS unless otherwise defined.
•
applications; InDesign CS and InCopy CS unless otherwise defined.
•
backing store; a container that manages the persistent boss objects that represent elements
in the logical structure of a document, represented in the API by kSBOSPageBoss. Each
InDesign CS document contains a root backing store, and each user-accessible story
(kTextStoryBoss) has its own backing store that contains the elements representing the
logical structure within the story.
•
boss class; a boss class is a compound type expression at the core of the application object
model. The term “boss” was orginally used to signify an entity that managed or “bossed”
a collection of interfaces. Boss classes represent objects in the application domain and
provide their behaviour; for instance, a publication (kDocBoss), a spread (kSpreadBoss),
a page (kPageBoss). A boss class can extend or subclass another boss class, but the
inheritance model allows for only a single superclass. Like an add-in, this type must
defined in the resource language ODFRez.
XML Productivity Features
7
XML Productivity Features
Terminology and definitions
•
boss object; an instance of a boss class.
•
comment, XML; a comment valid within an XML document, represented in the API by
kXMLCommentBoss. XML comments are defined in the XML 1.0 specification
[http://www.w3.org/TR/REC-xml] as follows:
“Comments may appear anywhere in a document outside other markup; in addition, they may
appear within the document type declaration at places allowed by the grammar. They are not part of
the document's character data...”
•
content handler; responsible for reading XML content from an input stream. There is an
extension point described in the section “Custom SAX Content handler” on page 75
which specifies how to customize handling of XML content to enable reading your own
custom data from a stream.
•
content item; an object in the native document model that can be associated with an
element in the logical structure. Examples are placeholder items
(kPlaceHolderItemBoss), images (kImageItem) and stories (kTextStoryBoss); these have
the interface IXMLReferenceData which stores the association with an element. A textrange within a story (kTextStoryBoss) is also a content item, since it can be tagged.
•
document element; element in the logical structure associated with the root node of the
native document model (kDocBoss), represented by kXMLDocumentBoss. A singleton
instance of this class is present in the document’s root backing store. You should be aware
that this is defined differently to “document element” in the XML 1.0 specification
[http://www.w3.org/TR/REC-xml], which is equivalent to root element in the InDesign
CS XML API.
•
document type declaration (DTD) defines the grammar for a class of documents,
represented by kXMLDTDBoss. The XML 1.0 specification
[http://www.w3.org/TR/REC-xml] defines a DTD as follows: ]
“The XML document type declaration contains or points to markup declarations that provide a
grammar for a class of documents. This grammar is known as a document type definition, or DTD.
The document type declaration can point to an external subset (a special kind of external entity)
containing markup declarations, or can contain the markup declarations directly in an internal
subset, or can do both. The DTD for a document consists of both subsets taken together.”
•
element; a node in the logical structure of an XML document, represented in the API by
boss classes that expose the interface IIDXMLElement. The XML 1.0 specification
[http://www.w3.org/TR/REC-xml] defines an element as follows:
“Each XML document contains one or more elements, the boundaries of which are either delimited
by start-tags and end-tags, or, for empty elements, by an empty-element tag. Each element has a
type, identified by name, sometimes called its “generic identifier” (GI), and may have a set of
attribute specifications. Each attribute specification has a name and a value.”
•
entity; these are containers for content in an XML document. There is an extension point
that lets you customize the behaviour of the application when dealing with external
entities; see “Custom SAX entity resolver” on page 77. The XML 1.0 specification defines
entities as follows:
An XML document may consist of one or many storage units. These are called entities; they all have
content and are all (except for the document entity and the external DTD subset) identified by entity
name.
8
XML Productivity Features
Terminology and definitions
•
generic identifier; name of an element in an XML document, which corresponds to the
tag-name
•
graphic frame; a placeholder for graphic content. In the API, boss classes (e.g.
kSplineItemBoss) that represent the behaviour of graphic frames aggregate an
IGraphicFrameData interface.
•
interface; in the domain of the API, refers to an abstract C++ class that is a descendant of
the API class IPMUnknown; interfaces are aggregated on boss classes to make their
capabilities accessible to client code.
•
logical structure; the logical structure of an InDesign CS document consists of a tree of
elements. The elements are represented by boss classes that have the interface
IIDXMLElement. The logical structure can also contain a DTD element, processing
instructions and comments.
•
ODFRez; a resource language. The OpenDoc Framework Resource Language that allows
cross-platform resources to be defined for plug-ins. Boss classes and add-ins must be
defined in ODFRez, along with data statements defining menu elements, user interface
widgets and so on.
•
persistence; this is defined by Webster’s as a “property of a programming language where
created objects and variables continue to exist and retain their values between runs of the
program” . Application documents are lightweight databases that maintain the state of
persistent boss objects which represent domain objects. See the chapter entitled Persistence
architecture for a more detailed discussion of this key topic.
•
persistent interface; strictly speaking, a “persistent implementation of an interface”; the
implementation must in its code use the macro CREATE_PERSIST_PMINTERFACE to
define that it implements a persistent interface, and provide a ReadWrite method where
its state is serialized.
•
persistent boss object; a boss object that saves its state across sessions. Persistent boss
classes, at least UID-based ones, aggregate the interface IPMPersist; instances of these
classes read and write their state to application databases (e.g. documents) through
persistent interfaces.
•
placed content; elements in the backing store which are associated with document content.
There is a small visual indicator in the structure-view that indicates whether an element is
associated with a placed content item. In terms of the model, this means that the
IIDXMLElement::GetContentItem returns something other than kInvalidUID.
•
placeholder; this is a target for XML import. It can be a graphic frame that has a tag
applied to identify it as a target for content from an XML import. If a text container is
marked-up, the placeholder is the story (kTextStoryBoss) rather than the containing
frame.
•
processing instruction; (PIs) these allow documents to contain instructions for
applications. They take the form <?application-name ... ?>. The XML 1.0 specification
notes that:
PIs are not part of the document's character data, but must be passed through to the application. The
PI begins with a target (PITarget) used to identify the application to which the instruction is
directed.
XML Productivity Features
9
XML Productivity Features
Terminology and definitions
10
•
root backing store; the instance of the backing store present by default in every document.
It stores the document element (kXMLDocumentBoss), any DTD element
(kXMLDTDBoss) and other elements including the root element (instance of
kTextXMLElementBoss) and its immediate children.
•
root element; element in the logical structure appears as the root element in the structureview. It is represented by an instance of the class kTextXMLElementBoss. By default, it
has a tag-name Root.
•
SBOS; small boss object store. The backing store (kSBOSPageBoss) uses this storage
mechanism; it is an example of container-managed persistence (CMP).
•
text-based marker; marked-up text in a story is enclosed by zero-width characters present
in the text model. These cannot be deleted individually, only in matched pairs. The
character inserted is represented in the text model by kTextChar_ZeroSpaceNoBreak [see
the SDK header file named public/includes/TextChar.h].
•
tag-name; associated with the name of an element, that is, its generic identifier in terms
used in the XML specification. A tag is represented in the API by kXMLTagBoss, which
also stores the colour as it appears in the Tags panel in the user interface.
•
tag-collection, tag-list; the set of tags that can participate in the logical structure of a
document. Represented in the API by IXMLTagList, stored in a workspace (e.g.
kDocWorkspaceBoss).
•
tagged content item; an instance of a content item that has been subject to tagging. In terms
of the model, this means that IXMLReferenceData::GetReference would return a valid
XMLReference.
•
tagging; the process of applying mark-up to content items. Note that it has no connection
with “tagged text”, a non-XML based format that the applications use to import and
export styled text. Content items that can be tagged aggregate the interface
IXMLReferenceData.
•
unplaced content; items can exist in the logical structure which are associated with text or
reference images, but are not present in the document layout and are not linked to items
in the native document model.
•
XML; eXtensible Mark-up Language is used for defining mark-up languages; it is a metalanguage rather than a language. Specification for current version defined as W3C
Recommendation [see http://www.w3.org/TR/REC-xml].
•
XML data; content that is defined in an XML based language
•
XML template; an InDesign CS document that has tagged place-holders into which XML
data can be flowed.
•
XSLT; eXtensible Stylesheet Language: Transformations. Specification for current version
defined as W3C Recommendation [see http://www.w3.org/TR/xslt].
XML Productivity Features
Introduction
Introduction
This document provides information about the XML-related features of the applications that
are relevant to the needs of systems integrators and plug-in developers in general. There is also
some detailed documentation on the XML features for end-users in the HTML-based help for
InDesign CS and InCopy CS, which should be consulted if you are unfamiliar with these
features.
This document has the following goals:
•
Sketch the application features supporting XML.
•
Explain how logical structure of InDesign CS documents is represented, in terms of the
classes and interfaces, their responsibilities and their associations.
•
Identify use cases involving XML.
•
Explain how to work with the InDesign CS XML API as a client.
•
Identify some XML-related extension points for InDesign CS.
XML itself is a specification that enables mark-up languages to be defined. An XML-language
is created for a particular purpose, with domain-specific semantics; for instance, DocBook is an
XML-based language for documenting software systems [http://www.oasisopen.org/docbook/xml/]. News Industry Text Format or NITF [http://www.nitf.org/] is an
example of an XML-based language for representing newspaper content.
There are several reasons why XML workflows might be used in print publishing:
1.
If content to be published is already available in an XML-based language, e.g. in NITF or
NewsML [http://www.newsml.org], that has already been customized for the publishing
domain.
2.
To maintain independence of content from both layout and styling information. This
goes beyond the separation of content and layout that is possible in a workflow with
InCopy CS and InDesign CS being used to edit copy and layout respectively.
3.
To support re-purposing of content for different media from a single source; for instance,
you might want to publish newspaper content to multiple media such as print, Web,
Adobe PDF and/or Mobile SVG.
4.
To capitalize on the large number of toolkits and standardized APIs that make it
relatively easy to manipulate XML documents.
5.
To take advantage of databases that are XML-aware.
Programming and the application object model
Rather than viewing InDesign CS programming as something exotic, we take the view that it is
not radically different from the object-oriented programming (OOP) model in OOP languages
XML Productivity Features
11
XML Productivity Features
Programming and the application object model
such as Java, C# or SmallTalk. The InDesign CS programming model is sufficiently different
from Microsoft COM that comparison with the latter is not very illuminating.
The design of the application is expressed in terms of boss classes that model domain objects
and the relationships between them. The view taken here is that analysis in terms of boss
classes provides the best way to understand the model. Interfaces represent aspects of boss
classes; interfaces do not typically represent domain objects. We try to focus attention on boss
classes to make explicit the design of the underlying data model.
In keeping with object-oriented methodology, we model the application as a community of
agents (boss objects) sending each other messages. We identify boss classes involved in
modelling the domain, their responsibilities and their collaborations with other boss classes.
This is the perspective taken when modelling a system using CRC cards [see Beck et al,
http://c2.com/doc/oopsla89/paper.html].
Since we are using object-oriented language to understand the model, we need to be explicit
about what we mean in the InDesign CS API by an object; we need to think in terms of boss
objects, instances of boss classes. We can consider their interfaces as a means of scoping
messages that are sent to boss objects.
The InDesign CS object model (ObjectModelLib component) supports the type-system based
on boss classes; it also manages loading and unloading of plug-ins. The object model is
responsible for creating and destroying boss objects. It is also responsible for tracking the plugins that are installed (IPlugInList) and maintaining metaclass information (IClassInfo) about
boss classes delivered by installed plug-ins.
12
XML Productivity Features
Programming and the application object model
FIGURE 1
Key parts of the object model
«library»
Object Model Lib
Plug-in List
Responsible for maintaining
a list of all the currently installed plug-ins.
See IPlugInList.
Responsible for storing
metadata about boss classes
known to the object model.
Class Dictionary
Interface Registry
Responsible for maintaining information
needed to create and destroy the
implementations (instances of C++ classes)
that make up boss objects.
See IClassInfo.
Not public API.
When you define boss classes and add-ins in an FR file of your plug-in using the ODFRez
resource language, the information in these type expressions ends up in the object model, in its
class dictionary. See the figure “Key parts of the object model” on page 13 for the main
components of the object model. The object model maintains meta-information about boss
classes that let you discover (for instance) what boss class a given interface belongs to by
writing code like this:
InterfacePtr<IControllingUnknown> boss(someInterface, UseDefaultIID());
// We know that IControllingUnknown is present by default on every boss class
ClassID classID = boss->GetClass();
InterfacePtr <IObjectModel> objectModel(gSession, UseDefaultIID());
TRACE("Boss class name is %s. ", objectModel->GetIDName(classID));
Modelling the domain
In the API, domain objects are modelled by boss classes, classes defined in an exotic resource
language named ODFRez. These classes are meaningful within the application’s object model.
If you are familiar with the object-oriented metaphor of a program as a community of
interacting agents sending each other messages, then you will be comfortable with the view
that you program InDesign CS by sending messages to boss objects. The set of messages a given
boss object understands depends on the interfaces that it exposes or aggregates. An interface is
an abstract C++ classes that is a descendant of the API class IPMUnknown. For instance, you
might send a message IIDXMLElement::FindChild to an object of class
kTextXMLElementBoss when working in the logical structure. The class
kTextXMLElementBoss extends the abstract boss class named kXMLElementBoss, which
provides the core behaviour for elements in the logical structure.
XML Productivity Features
13
XML Productivity Features
Programming and the application object model
You extend the application by delivering new boss classes in your plug-ins or decorating
existing ones with new interfaces via add-ins. More strictly, you can extend the application if
you deliver building blocks in your plug-in.
Boss classes and add-ins are the basis for these building blocks, which are software patterns
that fit into the applications’ extension points. For instance, an action component is a building
block that lets you add a menu item and be notified when your menu item is clicked on. We
describe some that are specific to XML in the section entitled “Extension points” on page 73.
The native document model and the (XML) logical structure are defined in terms of boss
classes. To represent the design of the native document model and the XML subsystem, we
adopt a UML-based notation with some domain-specific stereotypes and conventions.
A boss class consists of a set of interfaces and something to manage this collection; that is, boss
(i.e. manage) the interfaces. The managing entity is represented in the API by
IControllingUnknown, an interface present on every boss class by default.
FIGURE 2
Boss class in UML notation
IControllingUnknown
«boss class»
kXMLTagBoss
IXMLTag
IPersistUIDData
The figure entitled “Boss class in UML notation” on page 14 shows an example of a boss class
in this notation. Although IControllingUnknown is shown in this diagram, by convention, it is
omitted from the others. Other points about the notation are use of <<boss class>> as a
stereotype for a class. We do not attempt to display all the interfaces on a particular boss class,
only those relevant to the model being depicted.
A boss class defines the behaviour for instances of that class; the behaviour depends on the
semantics of interfaces that the boss class aggregates, and how they have been implemented.
If we write that a particular interface on a boss class has a responsibility for something, this is
shorthand for “the implementation class associated with a particular interface on a given boss
class” has a responsibility for something. Since this is an unwieldy expression, we prefer to
speak in terms of the responsibilities of interfaces on a particular boss class. For instance, we
write:
“The interface IXMLTagList is responsible for storing a collection of tags in a workspace...”
even though IXMLTagList is an abstract C++ class. What we mean by the statement is that the
implementation of the interface IXMLTagList is responsible for storing the collection of tags,
but we are contracting it so that we can write more compactly “The interface ... is responsible
for ...”, rather than having to obfuscate the meaning by introducing “implementation of ”.
We can now write that interfaces are responsible for storing something or doing something. For
instance, one particularly significant piece of information that they can store is a reference to
another object; for instance, one object can store a UID that refers to another object. This is
how the majority of the associations that we describe in sections such as “Key associations” on
page 24 are persisted.
14
XML Productivity Features
Features In InDesign CS
Features In InDesign CS
Character styles mapped to tags
The applications now support mapping both character styles and paragraph styles to tags, and
vice versa; InDesign version 2.0 supported only mapping paragraph styles. See the use case
entitled “Applying a mapping” on page 50.
Support for XSLT
The application now supports transformation of the incoming XML during import by
applying an XSL style sheet. This feature is intended to transform between XML grammars, for
instance, to allow data from data-sources in different XML languages to be imported into a
single XML template. This feature is concerned with mapping between XML grammars, not
styling the content on import. See the section entitled “XSL support” on page 68.
Validation against DTD
A document type declaration (DTD) can be associated with the logical structure of an
InDesign CS document. An InDesign CS document can be validated against the grammar the
DTD represents. The application reports any validation errors that occurred to the end-user
along with suggested corrections. See the section “DTD and validation” on page 61.
At the time of writing, the InDesign CS API does not support validating the logical structure of
a document against a grammar expressed in an XML schema
[http://www.w3.org/TR/xmlschema-0/].
Support for table headers and footers
InDesign CS now supports header rows and footer rows in tables; the XML support for
importing and exporting tables has been extended to support this and this information can be
round-tripped in XML files. See the use cases “Importing a table” on page 39 and “Exporting a
table to XML” on page 40.
Support for comments and processing instructions
InDesign CS now supports adding XML comments and processing instructions to the logical
structure of a document. See the section entitled “Processing instructions and comments” on
page 64.
Customising the SAX parser
There are extension points that are new for InDesign CS that let you customise the behaviour
of the XML parser. These include the ability to handle custom content in an XML document
being imported; see “Custom SAX Content handler” on page 75.
XML Productivity Features
15
XML Productivity Features
Walkthrough: importing XML into a template
Walkthrough: importing XML into a template
The intent of this section is to provide a walk-through of some of the XML features, before
considering the XML API in detail. We examine a basic but non-trivial workflow, where
images and structured text are imported into an InDesign CS document that has placeholders
for graphics and/or text-based content.
Whilst these are end-user features that we are going to walk through, you would automate
some of this in a workflow for a publishing system. The walk-through gives some context for
the discussion of the design that we introduce later.
Importing graphics
In this section, we work through a minimal example where we import a pair of images into an
XML template, in this case, based on a new document to which you will add one tag and two
graphic frames.
FIGURE 3
XML specifying images to import
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root>
<Image href="file://images/ColObj-1.gif"></Image>
<Image href="file://images/ColObj-2.gif"></Image>
</Root>
16
1.
Save the XML in the figure “XML specifying images to import” on page 16 to a file called
“image-example.xml” in the “examplefiles” folder in
<sdk>/source/sdksamples/xdocbookworkflow.
2.
Create a new document. Create a new tag called Image using the Tags panel (Window >
Tags). Make sure that you have the Structure view visible (View > Structure > Show
structure). Make sure that View > Structure > Show tagged frames is enabled also.
3.
Create two graphic frames with the Rectangle tool. Apply the Image tag to each by
selecting the graphic frame, and then clicking in the Tags panel.
XML Productivity Features
Walkthrough: importing XML into a template
FIGURE 4
Tagged placeholders for images
4.
Import the XML from “image-example.xml” into your document. You should see that
the images have been placed in the graphic frames you tagged.
5.
Try altering the ordering of the Image elements in the structure-view. This does not
change the layout, because we are not changing the content item (contained in a layout
object) each element in the logical structure is associated with.
Importing text
The example described in the shows “Importing graphics” on page 16 how graphic content can
be imported by references in the imported XML. Another important use case is importing
textual content with existing logical structure.
We can model the content of a publication as a set of articles, broken down into sections. One
option is to use an existing XML-based language that supported this content model. Another
option would be to define our own XML-based language, as shown in the worked
example“Transforming imported XML” on page 69. For this example we use the DocBook
model, or at least a very small subset of its large vocabulary.
Consider the DocBook XML in the figure entitled “Minimal XML file to be imported” on
page 17. Note that this is an instance of the book document type, which defines a set of articles.
FIGURE 5
Minimal XML file to be imported
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
<article>
<section>
<title>First</title>
<para>Hello world</para>
</section>
</article>
<article>
<section>
<title>Second</title>
<para>Hello world again</para>
</section>
</article>
XML Productivity Features
17
XML Productivity Features
Walkthrough: importing XML into a template
</book>
This XML file is to be imported into a template; the template chosen for the illustration was
based on one delivered in the CS SDK with small changes.
18
1.
Save the XML in “Minimal XML file to be imported” on page 17to a file called “textexample.xml”
2.
Open the template file in the “examplefiles” folder that can be found in
<sdk>/source/sdksamples/xdocbookworkflow; this template is named templatewin.indt
or templatemac.indt, depending on your platform. Delete the text frames on page 1, 2
and on the master pages. This is because we are going to create separate text frames
tagged “article”. This template by default has a story running through the master text
frames which is tagged “article”, so we have to delete the master text frames and the
individual text frames based on the master text frames.
3.
Save this untitled document as “xml-text-example.indd”.
4.
Add the tag “book” to the document “xml-text-example.indd”. You can do this either by
creating it through the Tags panel (Window > Tags) or by loading tags from the file
“text-example.xml”.
5.
You have to add the “book” tag at this point because you are going to change the tag on
the root element in the structure-view before the XML data is imported. Now change the
tag on the root element from “article” to “book”. Select the root element in the structureview and use the context-sensitive menu that appears on a right mouse click (Windows)
or control-click (Macintosh) to change the tag.
6.
Create two new text frames, and tag each with the tag “article”. This has the effect of
tagging the story running through the frame; be aware that the user-interface suggests
that the text frame is being tagged.
7.
Make sure that you have the Structure view visible (View > Structure > Show structure).
Make sure that View > Structure > Show tagged frames is enabled also. You should see
that there are two “article” elements that appear as placed content; in this case, each
“article” element has an association with a tagged story.
8.
Import the XML from “text-example.xml”.
XML Productivity Features
Walkthrough: importing XML into a template
9.
You should be able to see two articles on the page, and the structure view should
represent the logical structure within each article; that is, a section, a title and paragraph
as its children.
10. Choose the option to view text snippets from the Structure pop-out menu on the
Structure pane. Expand the elements of the structure and you should see something
similar to that below.
11. Try changing the order of the “title” and “para” elements in the structure-view by
dragging-and-dropping within the structure-view window (e.g. move the “para” element
above the “title” element). You will see the layout change, because the content items
associated with the elements are story ranges within a given story and re-arranging the
logical structure now affects the story order. Recall how re-ordering the “Image”
elements in the previous example didn’t affect the layout. Structure that is within a story
does affect the layout when it changes.
12. Place the text tool in one of the frames and bring up the story editor (Edit > Edit in story
editor). You should see a representation of the tags in the story editor view.
XML Productivity Features
19
XML Productivity Features
Key design concepts
FIGURE 6
Story editor view of story with XML mark-up
Key design concepts
This section introduces key design concepts that are needed to understand the design of the
XML subsystem. Other concepts that relate to the XML subsystem but that are less central to
understanding its design are dealt with in the Appendix (see “Appendix” on page 81); for
instance, the native document model (“Native document model” on page 81) and backing store
(“Backing store” on page 84) .
Logical structure
The logical structure of an InDesign CS document is a tree of elements representing logical
relationships between elements. XML data can be imported to create or modify the logical
structure of a document; see “Importing XML” on page 35. Existing content items can be
tagged to modify logical structure; this is described in the section entitled “Changing logical
structure by tagging content” on page 51.
FIGURE 7
Tagged content item
K4EXT8-,%LEMENT"OSS
K3PLINE)TEM"OSS
K8-,4AG"OSS
K0LACE(OLDER)TEM"OSS
The native document model specifies how end-user documents are represented by InDesign CS.
End-users work with spreads, pages, layout objects such as graphic frames, guides and so on,
and these are represented in the native document model.
The logical structure of a document consists of a tree of elements, which may have associations
with content items in the native document model.
20
XML Productivity Features
Key design concepts
The logical structure of an InDesign CS document can be exported as an XML document that
contains text, mark-up and references to images; see the section “Exporting XML” on page 36.
The logical structure of a document depends on:
1.
the tag collection, a list of tag objects (kXMLTagBoss) that belong to a workspace (e.g.
kDocWorkspaceBoss),
2.
the backing store (see “Backing store” on page 84), responsible for managing elements
and their links to content items in the document model, as well as links to tag objects.
The figure entitled “Tagged content item” on page 20 shows a minimal document, with a
single graphic frame (kSplineItemBoss) with a dependent placeholder item
(kPlaceHolderItemBoss). The placeholder item tagged with “Image”, stored in a tag object
(kXMLTagBoss). Elements (represented by boss classes with the interface IIDXMLElement)
are rendered in the structure-view, which is a view of a document’s logical structure.
FIGURE 8
Native document model and logical structure
Native document model
contentTagged
Logical structure
tagsUsed
Tags and the
tag-list
Backing
stores
When document content is marked-up or tagged, elements (represented by boss objects that
expose the interface IIDXMLElement) are created within the document’s logical structure and
contained in its backing store; see “Backing store” on page 84. Elements can also be created by
importing XML; see “Importing XML” on page 35.
Tagging creates associations between content items and elements in the logical structure.
Tagging also creates associations between objects representing tags (kXMLTagBoss) and the
elements in the logical structure. This is shown in the high-level diagram entitled “Native
document model and logical structure” on page 21 and described in more depth in the section
entitled “Key associations” on page 24.
XML Productivity Features
21
XML Productivity Features
Key design concepts
After tagging a content item:
1.
the backing store contains objects representing elements in the logical structure, which
refer to content items in the document model,
2.
the objects representing the elements in the logical structure are associated with tag
objects, which are contained in the tag-list stored in a workspace,
3.
content items in the document model have associations with objects representing
elements in the logical structure.
Importing XML into an InDesign CS document creates new elements in the logical structure.
This can result in content being automatically placed within the layout, or maintained as
unplaced content within the document’s logical structure, depending on whether the
document has tagged placeholder page items.
22
XML Productivity Features
Key design concepts
FIGURE 9
Instance diagram showing example of logical structure
«boss class»
document element : kXMLDocumentBoss
IIDXMLElement::GetNthChild
«boss class»
book (root) : kTextXMLElementBoss
No tag is associated with
the document element,
and it doesn't appear in the
structure-view
IIDXMLElement::GetTagUID
tag : kXMLTagBoss
IIDXMLElement::GetNthChild IIDXMLElement::GetNthChild
«boss class»
article : kTextXMLElementBoss
«boss class»
article : kTextXMLElementBoss
IIDXMLElement::GetNthChild
IIDXMLElement::GetNthChild
Boss objects representing
an element in the
logical structure can
have a link to an instance of
kXMLTagBoss that stores the
tag name
Only one is shown in the interests
of clarity in this diagram.
«boss class»
section : kTextXMLElementBoss
«boss class»
section : kTextXMLElementBoss
How this logical
structure would
be rendered in
the structure-view
window
The logical structure of an InDesign CS document consists of a tree of elements; each element
in the tree is represented by a boss object with the interface IIDXMLElement and has a link to a
boss object representing its tag (kXMLTagBoss). See the figure entitled “Instance diagram
showing example of logical structure” on page 23 for an instance of a logical structure. Note
how each element in the tree has an association linking it with a boss object that represents its
tag (kXMLTagBoss).
The logical structure is easier to work with than the native document model; see “Native
document model” on page 81. You may need different interfaces to navigate through the
XML Productivity Features
23
XML Productivity Features
Key design concepts
native document model, depending on your starting point and where you want to get to; for
instance, to navigate from the root node (kDocBoss) to a graphic frame on a spread would
require use of methods on the interfaces ISpreadList, ISpread and IHierarchy.
Navigation within the logical structure is easier; you can use a single interface. To navigate
through the logical structure, you can use methods on the interface IIDXMLElement,
regardless of your starting point and destination.
Key associations
The XML subsystem establishes associations between elements in the logical structure and
content in the native document model, at least for placed content or tagged placeholders.
Elements are also associated with tags that store their tag-names. The elements in the logical
structure are held in a backing store, and tagged content items can be associated with the story
(kTextStoryBoss) that owns the backing store; see “Backing store” on page 84.
There are several key associations maintained by the XML subsystem that we consider in detail
in this section:
1.
content items in the native document model are associated with elements in the logical
structure. The association is maintained via the interface IXMLReferenceData and the
helper class XMLReference; see “Association from native document model to logical
structure in UML” on page 25.
2.
Elements in the logical structure are associated with content items in the native
document model. The association is maintained by the interface IIDXMLElement; see
“Association from logical structure to native document model in UML” on page 26.
3.
Elements in the logical structure are associated with tags. The association is maintained
by the interface IIDXMLElement; see “Association from logical structure to tag in UML”
on page 27.
4.
Content items in the native document model are associated with the story
(kTextStoryBoss) that owns the backing store (kSBOSPageBoss). The association is
maintained by the interface IIDXMLElement; see “Associations involving content item
and backing store” on page 28.
The associations are shown in a structural diagram for a tagged placeholder in the figure
entitled “Tagged content item” on page 28. Since understanding these associations is the key to
understanding the XML model, each association is considered in the context of the example
introduced in the figure “Tagged content item” on page 20.
24
XML Productivity Features
Key design concepts
FIGURE 10
Association from native document model to logical structure in context
K4EXT8-,%LEMENT"OSS
K3PLINE)TEM"OSS
K8-,4AG"OSS
K0LACE(OLDER)TEM"OSS
Content items (with an IXMLReferenceData interface) can have an association with an
element in the logical structure. For instance, a tagged graphic frame that is a placeholder for
an image is represented an object of class kPlaceHolderItemBoss, with a parent of class
kSplineItemBoss; see figure “Association from native document model to logical structure in
context” on page 25. When the frame is tagged, an association is set up with an element in the
logical structure, of class kTextXMLElementBoss; see “Association from native document
model to logical structure in UML” on page 25.
FIGURE 11
«boss class»
kPlaceHolderItemBoss
Association from native document model to logical structure in UML
IXMLReferenceData
1
0..1
IIDXMLElement
«boss class»
kTextXMLElementBoss
«helper class»
XMLReference
Instantiate()
Boss classes that aggregate the interface IXMLReferenceData represent content items that can
be tagged; see “Native document model and XML-related interfaces” on page 83. In other
words, the interface IXMLReferenceData lets content items be linked to elements in the logical
structure, since it stores a reference to an element in the logical structure. If an item is not
tagged, then this reference will be invalid. An illustration of this association is shown in
“Association from native document model to logical structure in UML” on page 25.
XML Productivity Features
25
XML Productivity Features
Key design concepts
Along with content items, the class representing the root of the native document model
(kDocBoss) aggregates the interface IXMLReferenceData, which has the responsibility for
maintaining an association with the document element (kXMLDocumentBoss). Note that the
class kXMLDocumentBoss itself has two IXMLReferenceData interfaces with different
interface identifiers; one is responsible for maintaining an association with a DTD element, if
there is one (kXMLDTDBoss). See the structural diagram “Structural diagram involving
document element” on page 33.
FIGURE 12
Association from logical structure to native document model in context
K4EXT8-,%LEMENT"OSS
K3PLINE)TEM"OSS
K8-,4AG"OSS
K0LACE(OLDER)TEM"OSS
Elements in the logical structure have an association with one or zero content items. If they
represent placed content or a tagged placeholder, then they are associated with one content
item. If they are not placed (or they are structural elements) then they are associated with zero
content items. The example shown in the figure “Association from logical structure to native
document model in context” on page 26 is an example where the element represents a tagged
placeholder. The UML for this association is shown in the figure “Association from logical
structure to native document model in UML” on page 26
FIGURE 13
Association from logical structure to native document model in UML
IIDXMLElement
«boss class»
kTextXMLElementBoss
1
IIDXMLElement::GetContentItem
«boss class»
kPlaceHolderItemBoss
0..1
The interface IIDXMLElement lets an element in the logical structure be associated with a
content item. It stores a reference to a content item, which is invalid if the element is not
26
XML Productivity Features
Key design concepts
associated with placed content or a tagged placeholder. An illustration of this association is
shown in the figure entitled “Association from logical structure to native document model in
UML” on page 26. Note that any content item (exposing the interface IXMLReferenceData)
could be substituted for kPlaceHolderItemBoss in this diagram.
FIGURE 14
Association from logical structure to tag in context
K4EXT8-,%LEMENT"OSS
K3PLINE)TEM"OSS
K8-,4AG"OSS
K0LACE(OLDER)TEM"OSS
Elements in the logical structure are associated with tags, that store the element’s tag-name.
This is shown in the context of the example of a tagged placeholder in the figure “Association
from logical structure to tag in context” on page 27.
FIGURE 15
Association from logical structure to tag in UML
1
«boss class»
kTextXMLElementBoss
IIDXMLElement
IIDXMLElement::GetTagUID
0..1
«boss class»
kXMLTagBoss
IXMLTag
The interface IIDXMLElement lets an element in the logical structure be associated with a tag;
it stores a reference to an tag object (kXMLTagBoss) which is populated with a tag whose name
corresponds to the element’s tag-name. This is shown in the figure entitled “Association from
logical structure to tag in UML” on page 27.
The interface IXMLReferenceData can be used to obtain an XMLReference object; this lets you
acquire a reference to the object representing an element (e.g. kTextXMLElementBoss), as well
as to the object that owns the backing store, which will be an instance of kTextStoryBoss.
XML Productivity Features
27
XML Productivity Features
Key design concepts
FIGURE 16
«boss class»
kPlaceHolderItemBoss
Associations involving content item and backing store
IXMLReferenceData
1
0..1
«boss class»
kTextStoryBoss
«helper class»
XMLReference
GetUID()
owns
1
1
«boss class»
kSBOSPageBoss
Represents a backing store, which
manages a collection of elements (with
the interface IIDXMLElement)
We have considered the associations of elements with content items and with tags. To
complete the picture, we note that the elements are held in backing stores (see “Backing store”
on page 84), and that there is a further association between the content item and the story
(kTextStoryBoss) that manages the backing store. This is shown in the structural diagram
entitled “Associations involving content item and backing store” on page 28. Note that any
content item (exposing the interface IXMLReferenceData) could be substituted for
kPlaceHolderItemBoss in this diagram.
FIGURE 17
Tagged content item
K4EXT8-,%LEMENT"OSS
K3PLINE)TEM"OSS
K8-,4AG"OSS
K0LACE(OLDER)TEM"OSS
We will now introduce a more detailed structural diagram for a tagged placeholder with these
associations and other key classes; see figure “Tagged content item” on page 28.
28
XML Productivity Features
Key design concepts
FIGURE 18
Backing store and tagged page item
Each story has an associated backing-store
that manages a collection of elements (with
interface IIDXMLElement) representing the
logical structure within the story.
Graphic frame tagged
as placeholder
«boss class»
kSplineItemBoss
Use IXMLReferenceData
to get XMLReference
IHierarchy::GetChildUID
«boss class»
kPlaceHolderItemBoss
The root backing store contains the elements
that are not tied to a specific user-accessible
story.
«helper class»
XMLReference
GetUID()
«boss class»
kTextStoryBoss
IXMLReferenceData
1
1
Association from native
document model to
logical structure
0..1
Backing store
1
«boss class»
kSBOSPageBoss
«helper class»
XMLReference
Instantiate()
owns
1
stores
0..1
This class is a container
for the objects representing
elements in the logical structure
1..*
1
IIDXMLElement::GetContentItem
«boss class»
kTextXMLElementBoss
IIDXMLElement
1
IIDXMLElement::GetTagUID
Association from logical structure
to native document model
1
«boss class»
kXMLTagBoss
Anything that aggregates IIDXMLElement
can occur in the root backing store.
Other backing stores contain boss
objects that aggregate IIDXMLElement
except for the document element
(kXMLDocumentBoss) and the
DTD element (kXMLDTDBoss)
1..*
IXMLTagList::GetTag
1
«boss class»
kDocWorkspaceBoss
The diagram in the figure entitled “Backing store and tagged page item” on page 29 shows the
classes and associations involved when a graphic frame is tagged as a placeholder for an image,
which includes some of the associations already introduced.
XML Productivity Features
29
XML Productivity Features
Key design concepts
If an image is placed, then the boss class kPlaceHolderItemBoss is replaced in the model by the
boss class representing the image (e.g. kImageItem, kEPSItem, kPlacedPDFItemBoss and so
on. To find out more about the data model for a tagged story or text range, see “Tagging text”
on page 57. To find out more about the relationships that exist. in an empty document, see
“Document element and root element” on page 32
The object diagram entitled “Instance diagram for a tagged content item” on page 31 is based
on the example “Tagged content item” on page 28; you should also consult the structural
diagram entitled “Backing store and tagged page item” on page 29, which this instance
diagram is a realisation of.
The instance diagram makes explicit the links that exist between the objects representing
elements in the logical structure and (a) content items and (b) tags.
You should be aware that although the instance diagram shows properties of the boss objects,
this is just a device to make the notation more compact. In practice the properties would be
accessed through an interface, and stored by a persistent implementation of an interface. For
instance, the properties such as the tag UID and the content item UID are accessed through the
interface IIDXMLElement, and stored by its persistent implementation kXMLElementImpl.
30
XML Productivity Features
Key design concepts
FIGURE 19
Instance diagram for a tagged content item
«boss class»
XML-story : kTextStoryBoss
UID = 92
Instance of a story that is
present in every document,
a non-user-accessible story.
The UID is specific to this example; you
should not expect it always to be 92.
owns
«boss class»
placeholder item : kPlaceHolderItemBoss
UID = 138
Class that represents the backing
store. Although its architecture is
opaque to client code, the interfaces
like IIDXMLElement indicate how the
elements are stored within the backing
store
«boss class»
root backing store : kSBOSPageBoss
stores
hasContent
stores
stores
«boss class»
document element : kXMLDocumentBoss
LSID = 1
BaseUID = 92
«boss class»
root element : kTextXMLElementBoss
LSID = 2
BaseUID = 92
ContentItemUID = 0
TagUID = 107
hasTag
Elements present by default
in a newly created document.
Note the LSID (logical store identifier)
is equivalent to a record number within
the backing store.
The BaseUID refers to the kTextStoryBoss
that owns the backing store.
«boss class»
Root tag : kXMLTagBoss
UID = 107
«boss class»
image 1 : kTextXMLElementBoss
LSID = 3
BaseUID = 92
ContentItemUID = 138
TagUID = 137
hasTag
«boss class»
Image tag : kXMLTagBoss
UID = 137
An element we created that is linked to
a placeholder item for an
image. This is specific to the example.
Since we have linked it to a content item
in the native document model,
the ContentItemUID is now something other
than zero (kInvalidUID).
XML Productivity Features
31
XML Productivity Features
Key design concepts
Document element and root element
This section examines the role of two key objects present in the logical structure of any
InDesign CS document and explains how they fit into the design. These objects are the
document element and root element.
The document element (represented by kXMLDocumentBoss) is associated with the root node
in the document model (kDocBoss). The document element is responsible for managing
document-level information, such as any associated DTD and document-level comments or
processing instructions. This is not equivalent to the “root, or document element” of the XML
specification [http://www.w3.org/TR/REC-xml] because it does not have an associated tag and
is not represented when XML is exported from InDesign CS. This element is not shown in the
structure-view.
The root element (an instance of kTextXMLElementBoss) is the root of the element hierarchy
in the logical structure. By default it has the tag “Root”. This is equivalent to the “root
element” in the XML specification.
32
XML Productivity Features
Key design concepts
FIGURE 20
Structural diagram involving document element
The root element is represented
by kTextXMLElementBoss.
In an empty document, the root
element has the tag-name "Root".
«boss class»
kTextXMLElementBoss
IIDXMLElement
«helper class»
XMLReference
Instantiate()
The helper class XMLReference is used
to navigate the association. It is obtained
from IXMLReferenceData and lets one
acquire a reference to a boss object that
supports IIDXMLElement.
«helper class»
XMLReference
Instantiate()
«boss class»
kDocBoss
IXMLReferenceData
The interface IXMLReferenceData
on kXMLDocumentBoss stores a
reference to the root element of
the document, "Root" by default
«boss class»
kXMLDocumentBoss
IXMLReferenceData
IIDXMLElement
IXMLReferenceData (IID_IXMLDTDXMLREFERENCEDATA)
There is a second IXMLReferenceData
interface on kXMLDocumentBoss with an
exotic interface identifier that stores a
reference to the DTD element
The class kXMLDocumentBoss is unique
in that it has both IIDXMLElement and
IXMLReferenceData interfaces.
The instance of the document element
(kXMLDocumentBoss) is held in
the root backing store.
«boss class»
kXMLDTDBoss
IIDXMLElement
«helper class»
XMLReference
Instantiate()
If you are familiar with the XML specification, then you should be cautious because
“document element” has a different meaning within the InDesign CS API to the XML
specification, which treats document element and root element as the same thing. In the
InDesign CS API, document element and root element are two distinct concepts.
As shown in the figure “Structural diagram involving document element” on page 33, the
document element (kXMLDocumentBoss) is associated with the root node of the native
document model (kDocBoss). The interface IXMLReferenceData on kDocBoss stores a
reference to the document element (kXMLDocumentBoss).
The logical structure is held in the backing store of an InDesign CS document; see the section
entitled “Backing store” on page 84. The document element and root element are held in the
root backing store, along with other immediate children of the root element; see “Root backing
store and notification” on page 86.
XML Productivity Features
33
XML Productivity Features
Key design concepts
Importing and exporting XML
When XML data is imported, the XML subsystem creates elements in the logical structure (see
“Logical structure” on page 20). XML content can be imported into an XML template, which
has place-holder items with tags that match element names in the XML data to be imported.
An example is shown in the section “Walkthrough: importing XML into a template” on
page 16.
1.
If there are tagged content items in the layout that match the element tag-names in the
imported XML, then content is automatically placed on import; that is, images would be
placed in the graphic frames containing the placeholder (kPlaceHolderItemBoss) or
flowed into the story (kTextStoryBoss) that was tagged.
2.
If there are no matching tagged items in the layout, then elements are created in the
logical structure, but their content is held in the backing store without being placed; see
“Backing store” on page 84.
Import of XML does not use the standard import service architecture, but rather a specialised
XML parser service (kXMLParserServiceBoss). Export of XML uses the standard export service
architecture (see IExportProvider). See the section entitled “Import and export” on page 35 for
more detail on the import and export of XML.
Suites and utilities
XML suites
A suite is a API that lets you program at a level of abstraction above the model, dealing only in
terms of an abstract selection. You should consult the tech-note on Selection architecture
(#10006) for more detail on what is meant by a suite. A selection can be created either by an
end-user, or sometimes programmatically, so a suite interface may be used to automate tasks
even if an end-user is not able to make a selection.
There are some suite interfaces that can be used to program the XML features, which represent
a fairly high level of abstraction over the XML subsystem. These suites are recommended as a
first point of call if you are programming the XML features.
34
•
IXMLNodeSelectionSuite can be used to make a programmatic selection in the structureview window.
•
IXMLStructureSuite can be used when there is a selection in the structure-view window.
It lets you change the logical structure of a document at the node selected in the
structure-view tree. If you are writing client code that will involve the end-user making
active selections, this is one mechanism to modify the logical structure tree. The methods
on this suite interface delegate to the command facades.
•
IXMLTagSuite can be used to apply tags to a selection, such as a text range or graphic
frame(s). It can also be used for other purposes such as adding a processing comment to
the document’s logical structure; see the use case “Adding comments and processing
instructions” on page 66.
XML Productivity Features
Import and export
You can extend the application by writing a custom suite that would be available when there is
a selection in the structure-view window. See the section on “Extension points” on page 73 and
the tech-note on Selection for more assistance.
Command facades and utilities
There are many command-related boss classes named kXML<whatever>CmdBoss but in most
cases you do not need to process these low-level commands, as there are facades you should use
that encapsulate parameterizing and processing these commands.
Interfaces such as IXMLUtils, IXMLElementCommands, IXMLMappingCommands,
IXMLTagCommands and IXMLAttributeCommands are instances of command facades.
These encapsulate processing of almost all of the commands required by plug-in code; you will
also find that most of the data interfaces in the XMedia are not required by client code, since
they relate to commands that are processed by one of these wrapper interfaces. These interfaces
are aggregated on kUtilsBoss; there is a smart pointer class Utils that makes it straighforward to
acquire and invoke methods on these interface. You can invoke their methods by writing code
that follows the pattern:
Utils<IXMLElementCommands>()->MethodName(...)
You should always look first at the IXMLUtils or IXML<whaver>Commands interfaces, to see
if there is a method that serves your purpose on one of these interfaces to avoid processing
low-level commands.
There are perhaps some low-level commands that you may need to process, where there are
gaps in the facade. The use cases indicate whether a low-level command would need to be
processed to execute the use case.
Import and export
Feature description
Importing XML
The application supports import of XML encoded as:
•
UTF-8 [http://www.ietf.org/rfc/rfc2279.txt],
•
UTF-16 [http://www.ietf.org/rfc/rfc2781.txt],
•
Shift-JIS, [http://www.w3.org/TR/2000/NOTE-japanese-xml-20000414/], a two-byte
format for Japanese.
The workflow within InDesign CS is a little different to other structured editors, such as
FrameMaker + XML, where there is a single flow of text and the logical structure of the
document is determined by a single XML. With InDesign CS, you can import several XML files
into the logical structure of the document. You can also export a subset of the document
logical structure into an XML file
There are two main workflows:
XML Productivity Features
35
XML Productivity Features
Import and export
1.
Importing the XML into the backing store, and then manually placing onto the layout to
set up the associations between elements in the logical structure and document object.
2.
Creating an InDesign CS document as an XML-template that contains placeholders;
these placeholders are tagged with names of the elements in the XML data to import. The
contents of the XML file can be flowed into the placeholders by the application as it is
imported. The order that the elements appear in the logical structure determines how the
content is flowed into the tagged placeholders.
To import content, there are several options that are available on the Import XML options
dialog:
1.
“Replace Content” replaces existing tagged layout objects from where the root of the
XML file matches the tag of the selected element. Select this option if you are using a
template with tagged placeholders.
2.
“Append Content” can be used to create new elements at the end of the document logical
structure.
3.
“Import into Selected Element” can be used to import XML content into the element
selected in the Structure pane. If this option is not selected, imported elements will
appear under the root element.
Exporting XML
You can export the logical structure of an InDesign CS document as an XML document; the
export takes place in document order [http://www.w3.org/TR/xpath, Section 5], meaning that
the logical structure of the InDesign CS document and exported XML are the same.
By default, an empty InDesign CS document has a single element “Root” in its logical
structure. If a new InDesign CS document is created and exported as XML, then a single
element <Root/> is written to the output file; see “Structure of empty document and XML
exported” on page 36.
FIGURE 21
Structure of empty document and XML exported
"[POYHUVLRQ HQFRGLQJ 87)VWDQGDORQH \HV"!
5RRW !
There are a couple of points to note about the relation between XML exported from InDesign
CS and the logical structure:
1.
36
XML content can be exported from a document even if it is not associated with placed
content in the document. XML exported is based on the logical structure, irrespective of
whether the elements are associated with content in the document.
XML Productivity Features
Import and export
2.
The order in which the elements appear in the output XML is based entirely on the
logical structure, and has no direct relation with the document native model. The
exception to this is the case of a story with mark-up, where the order of the elements in
the logical structure within the sub-tree corresponding to the story corresponds to the
story reading order.
By default, InDesign CS does not support exporting a selection within the layout window and
will export the entire document; however, note that you can export a selection of tags within
the Tags panel. You can write additional code to allow an end-user to export a layout selection.
Note that a selection within the structure-view window can be exported.
Design
Unlike other forms of import, e.g. EPS (import provider kEPSPlaceProviderBoss) or PDF
(import provider kPDFPlaceProviderBoss) say, importing XML does not use the standard
import provider (IImportProvider) architecture. Rather, it relies on an XML parser service,
represented by the class kXMLParserServiceBoss; this has the ServiceID of kXMLParserService
and a service interface of ISAXServices.
The behaviour of XML parser (kXMLParserServiceBoss) is controlled by ISAXParserOptions;
see InCopyDocUtils.cpp (<sdk>/source/sdksamples/incopyfileactions) for an instance of this
being used. Parsing errors are stored in the interface IXMLServicesError exposed by the parser
boss class.
The import process depends on SAX content handler services (see ISAXContentHandler). The
default top-level content handler for importing XML is kSAXDocumentHandlerBoss; see the
description of content handlers in the section entitled “Custom SAX Content handler” on
page 75. The XML parser service also looks for all other SAX content handler services and
registers them, to enable them to handle content during parsing if they choose.
Controlling the parser becomes particularly relevant when you implement your own custom
SAX content handler and use it as the top-level handler; see “Custom SAX Content handler”
on page 75.
XML Productivity Features
37
XML Productivity Features
Import and export
FIGURE 22
Interfaces storing options for import and export
Options that are stored
in a specific document
«boss class»
kDocWorkspaceBoss
IXMLExportSessionOptions
«boss class»
kWorkspaceBoss
IXMLImportOptions
IXMLExportOptions
IXMLImportOptions
IXMLExportOptions
Session-specific options and
options inherited by new
documents
An XML file can be exported when content objects have been tagged; this can be based on a
selection from the logical structure via the structure view or the logical structure of the entire
document. See the snippet named SnpImportXML.cpp in the folder
<sdk>/source/sdksamples/codesnippets for an example of using the import service and
controlling the XML import options.
Alternatively, you can make a programmatic selection in the structure-view prior to the import
to determine where the imported XML should be located in the logical structure. See the FAQ
entitled “How do I make a selection in the structure view?” on page 78.
XML export takes place using the standard export service architecture. See the snippet named
SnpExportXML.cpp in the folder <sdk>/source/sdksamples/codesnippets for an example of
using the XML export service.
Importing XML data
There is a command named kImportXMLFileCmdBoss which can be processed to import an
XML file. It has data interfaces as follows:
38
•
an interface IImportFileCmdData, specifying the target database (document) for the
import and the path to the file to import,
•
an interface IStylesheetData, specifying an XSLT style sheet (if any) to apply on import;
see the section “Support for XSLT” on page 15,
•
an interface IXMLReferenceData used to specify the parent element in the existing logical
structure.
XML Productivity Features
Import and export
The behaviour of the command to import XML depends on the import options (see
IXMLImportOptions); see the diagram “Interfaces storing options for import and export” on
page 38. The options can be changed through processing a command of class
kChangeXMLImportOptionsCmdBoss.
There is a snippet named SnpImportXML.cpp that shows in more detail an instance of
processing this command, and see also XDocBookWorkflow code for another example of
programmatic import of XML. The relevant code can be found in the folder named
<sdk>/source/sdksamples/xdocbookworkflow.
Importing XML via this command (kImportXMLFileCmdBoss) means that you are limited to
the default entity resolution of the application. If you have more advanced requirements and
you want to provide your own entity resolver for use during the import process, then you need
to write a custom import XML command of your own. See the section entitled “Custom SAX
entity resolver” on page 77.
Exporting XML data
Exporting XML goes through the standard export provider architecture, so you can obtain an
XML export service from the service registry (IK2ServiceRegistry) knowing the ServiceID
identifying an export service (kExportProviderService) and a ClassID for the XML export
service (kXMLExportProviderBoss).
You can find code showing XML export in the SDK code-snippet named SnpExportXML.cpp
(<sdk>/source/sdksamples/codesnippets) and the SDK sample named XDocBookWorkflow
(<sdk>/source/sdksamples/xdocbookworkflow)
Importing a table
A table defined in an XML file can be imported into InDesign CS.This can be imported in at
least two ways;
1.
As part of an XML document that they are importing, in which case the table elements
are silently consumed on import.
2.
As a stand-alone XML file that contains the specification for a single table. If the root
element of this XML file is a table element, then it is possible to import this into a selected
node in the logical structure.
If the table is to be imported unplaced, i.e. directly into the backing store without there being a
selected element in the logical structure, the “table” element has to be wrapped in some other
element (e.g. “Story”), since the “table” element and its sub-tree of dependents is stripped on
import.
One key point is that once InDesign CS has imported the table, it is no longer a “structured”
table and cannot be manipulated through the structure-view, or programmatically via
manipulating the logical structure.
The SDK sample named XDocBookWorkflow (located in the folder
<sdk>/source/sdksamples/xdocbookworkflow) shows one mechanism to work with tables that
are defined in a XML-based language that uses a different content model for tables to the
HTML-based content model. Ideally, use a custom SAX content handler to strip out the table-
XML Productivity Features
39
XML Productivity Features
Import and export
related elements on import (see “Extension points” on page 73) rather than directly deleting
them from the logical structure, as XDocBookWorkflow does.
Exporting a table to XML
The precondition for exporting a table from InDesign CS is that it is contained in a tagged
story. If it is not, then the default behaviour is to ignore on export. If it is contained in a tagged
story, then it will be exported to a content model that is based on that for HTML tables; see
[http://www.w3.org/TR/REC-html40/struct/tables.html] and the RFC document from the
IETF at [http://www.ietf.org/rfc/rfc1942.txt].
The main difference is that the table content is qualified by an Adobe namespace, referred to by
“aid” or “InDesign”, which can be found defined as:
xmlns:aid="http://ns.adobe.com/AdobeInDesign/3.0/"
xmlns:InDesign="adobe:ns:InDesign/"
For instance, exporting a table that contains two columns, a header row, two body rows and
footer row results in the XML fragment shown in the figure entitled “Exported table” on
page 41.
40
XML Productivity Features
Tags and the tag-list
FIGURE 23
Exported table
- <aid:table xmlns:aid="http://ns.adobe.com/AdobeInDesign/3.0/">
- <aid:thead>
- <aid:tr>
<aid:td>Header cell 1</aid:td>
<aid:td>Header cell2</aid:td>
</aid:tr>
</aid:thead>
- <aid:tbody>
- <aid:tr>
<aid:td>Body cell1 content</aid:td>
<aid:td>Body cell2 content</aid:td>
</aid:tr>
- <aid:tr>
<aid:td>Body cell 3 content</aid:td>
<aid:td>Body cell 4 content</aid:td>
</aid:tr>
</aid:tbody>
- <aid:tfoot>
- <aid:tr>
<aid:td>Footer cell 1</aid:td>
<aid:td>Footer cell 2</aid:td>
</aid:tr>
</aid:tfoot>
</aid:table>
Tags and the tag-list
Feature description
End-users can load a set of tags through executing the menu item on the pop-out menu of the
Tags panel to populate the tag-list; see the figure “Tags panel and structure view” on page 42.
Tags can be loaded from several datasources:
1.
An InDesign CS tag-file, an XML document containing only tag-specific information.
2.
Any XML document that is an instance of the document type that is being worked with.
3.
By associating a DTD with the document. Doing this means that the DTD is parsed for
element tag-names and tags are created correspondingly. Note that at the time of writing,
elements that are defined within entities are ignored.
FIGURE 24
Sample tag-list
<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<article colorindex="4">
<articleinfo colorindex="6"/>
... (other elements omitted)
<ulink colorindex="19"/>
XML Productivity Features
41
XML Productivity Features
Tags and the tag-list
</article>
It is also possible to specify the colour of the tag using RGB co-ordinates, which is used for any
tags defined with a “Custom” colour. The co-ordinates are encoded using the scheme
described in the section “Hex encoded numbers” in the InCopy story format specification (see
tech-note #10083). For instance, a single tag with a custom colour that is the RGB co-ordinate
(0,0,255) appears as:
<link rgb="0 0,0 0,3ff00000 0"/>
In addition, there is an extension point that lets you customize what tags are created when an
XML document is being parsed; for instance, you might want to ignore some elements in the
input XML. This extension point is described in the section “Custom tag service” on page 76
FIGURE 25
Tags panel and structure view
An end-user can create a new tag by making a gesture involving the Tags panel, which adds an
entry to the tag list. Creating a new tag means that it is now available to mark-up content or tag
placeholder graphic frames for content. An end-user can delete a tag with a gesture involving
the Tags panel.
An end-user can export the tag-list by executing a pop-out menu item on the Tags panel.
Design
The tags that can be applied to mark-up content items in a document are stored in the tag-list
(IXMLTagList), a collection of tag objects (kXMLTagBoss) that is stored in a workspace.
42
XML Productivity Features
Tags and the tag-list
FIGURE 26
Structural model for tags and tag-list
The tag-list is a collection
of kXMLTagBoss objects
stored in a workspace object
«boss class»
kDocWorkspaceBoss
IXMLTagList
ISubject
«boss class»
kWorkspaceBoss
1
IXMLTagList
ISubject
1
IXMLTagList::GetTag
IXMLTagList::GetTag
Multiplicity is at least one at the
tag end, because every document
by default has the tag Root.
Multiplicity is zero at the
kXMLTagBoss end because
the session workspace by
default has no tags
1..*
0..*
«boss class»
kXMLTagBoss
The methods needed to
create, update properties of
and delete tags are found in
IXMLTagCommands on the
class kUtilsBoss
IXMLTag
IPMPersist
Tags are UID-based persistent objects,
hence the interface IPMPersist
The name and color for the UI
are stored in IXMLTag.
The boss class named kXMLTagBoss that represents an individual entry in a tag-list. The
signature interface of this boss class is IXMLTag; this stores properties such as the name and
the colour in the user-interface. The tag-list is represented by IXMLTagList, which is:
•
aggregated on the session workspace (kWorkspaceBoss); tags that would be present in
any newly created document,
•
aggregated on the document workspace (kDocWorkspaceBoss); tags that are present in a
given document.
Tagging relationships are represented by associations between classes representing elements in
the logical structure and those representing tags. For instance, if a graphic frame is tagged for
use as a placeholder, then an association is created between the placeholder boss object (an
instance of the class kPlaceHolderItemBoss) and an instance of the class
kTextXMLElementBoss. An association is created between an element in the logical structure
XML Productivity Features
43
XML Productivity Features
Tags and the tag-list
(kTextXMLElementBoss) and an instance of kXMLTagBoss to represent the tagging. See the
figure “Structural diagram for tagging placeholder item” on page 56 for this association.
Loading tags
Loading tags can be performed using the command facade IXMLTagCommands, present on
the boss class kUtilsBoss. Loading tags means changing the tag-list (IXMLTagList) stored in
the active workspace:
1.
if there is no document, the target for the change is the session workspace
(kWorkspaceBoss)
2.
if a document is open, the target for the change is the document workspace
(kDocWorkspaceBoss)
See the figure “Loading a new tag list” on page 44 for code illustrating this.
FIGURE 27
Loading a new tag list
// Let db be target database (e.g. document into which tags are to be loaded),
// and tagsSysFile be path to tag file to load
InterfacePtr<IXMLTagList> tagList(
Utils<IXMLUtils>()->QueryXMLTagList(db));
ErrorCode err = Utils<IXMLTagCommands>()->
LoadTagList(::GetUIDRef(tagList), tagsSysFile);
See the snippet <sdk>/source/sdksamples/codesnippets/SnpPerformXMLTags.cpp for an
example of this code being used in a richer context.
Tag lists (see IXMLTagList) are held in the document workspace (kDocWorkspaceBoss). A list
of tags loaded into a document, making them available to mark-up content in that document.
The contents of the tag list should be manipulated using IXMLTagCommands, not changed
through direct modification of the tag-list, otherwise you can corrupt the document.
See the section entitled “Saving tags” on page 44 for the format of the tag list XML file.
Under the hood, the low-level command kLoadTagListCmdBoss is processed whenever a taglist is imported. See the table “Low-level command notification details” on page 87 if you want
to find out more about how to observe this being processed by the application.
Saving tags
The tag list (IXMLTagList) is exported as an XML document, with elements specifying the
name and the colour index for each of the tags. The root element in the logical structure has
the same name as the root-element in the exported tag-list and names of the other elements
match those in the tag-list. A fragment of a tag-list is shown in the figure “Sample tag-list” on
page 41. To save a tag-list programmatically, you can use IXMLTagCommands.
FIGURE 28
//
//
//
//
44
Saving a tag-list
Assume that db refers to the document database from which tags are exported,
and sysFile is the path to the file to save.
SDKFileSaveChooser (in SDK)
is useful for selecting a file in this context
XML Productivity Features
Tags and the tag-list
InterfacePtr<IXMLTagList> tagList(Utils<IXMLUtils>()->QueryXMLTagList(db));
ErrorCode err =
Utils<IXMLTagCommands>()->SaveTagList(::GetUIDRef(tagList), sysFile);
See the snippet <sdk>/source/sdksamples/codesnippets/SnpPerformXMLTags.cpp for a more
complete example of implementing this use case.
Creating, updating and deleting tags
Tags are represented in the API by kXMLTagBoss, with the key interface IXMLTag. Tag objects
(instances of the class kXMLTagBoss) are managed by the IXMLTagList interface on
kDocWorkspaceBoss or kWorkspaceBoss.
Since IXMLTagList is part of the model, changes to IXMLTagList must go through a low-level
command. The facade interface IXMLTagCommands encapsulates the low-level commands
that are required to make these changes.
Programmatically, a tag can be created with the facade interface IXMLTagCommands, which
has a method CreateTag. See the figure “Creating a tag” on page 45, which shows code from
the file SnpPerformXMLTags.cpp in the folder <sdk>/source/sdksamples/codesnippets. On
executing this code successfully, createdTagUID is the UID of an instance of kXMLTagBoss.
FIGURE 29
Creating a tag
// Let tagName specify desired tag name
UID tagColorUID = kInvalidUID; // let the application pick a colour
Utils<IXMLTagCommands> tagCommands;
UID createdTagUID = kInvalidUID;
ErrorCode createErr = tagCommands->CreateTag (::GetUIDRef(tagList),
tagName,
tagColorUID,
&createdTagUID);
Under the hood, the low-level commands kXMLCreateTagCmdBoss and
kXMLSetTagColorCmdBoss are processed. If you want to see the notification scheme for these
commands, consult the table “Low-level command notification details” on page 87.
You can delete tags and update the properties of tags using the facade interface
IXMLTagCommands, aggregated on the boss class named kUtilsBoss.
Under the hood, deleting a tag processes the low-level command kXMLDeleteTagCmdBoss.
See the table “Low-level command notification details” on page 87 if you want to be notified
when this change happens.
XML Productivity Features
45
XML Productivity Features
Mappings between tags and run-styles
Mappings between tags and run-styles
Feature description
FIGURE 30
User interface for mapping tags to styles
An end-user can choose to apply a mapping between element names and run-styles (character
and paragraph styles). Once the mapping is applied to a document, then any marked-up text
will be styled as specified by the style on the right-hand-side of this mapping.
An important use-case for mapping tags-to-styles is to prepare a document for XML import;
assuming that XML-based content does not carry style information, the tag-to-style map is an
basic mechanism to apply styling to inbound XML-based content. We are describing it as basic
compared to for instance styling based on XSLT or a proprietary mechanism such as Adobe
FrameMaker’s Element Definition Document (EDD). The FrameMaker EDD is effectively a
style sheet containing rules specifying how to map tags to styles but in a context-dependent
way.
FIGURE 31
Unstructured document
An end-user can apply structure to an unstructured InDesign CS document by choosing to
map run-styles to tags. The effect of this is to mark-up the text ranges that have the styles on
the left hand side of the style-to-tag mapping. The end-user is warned that applying a style-totag mapping can restructure the document; see the figure entitled “Styles-to-tags user
interface” on page 47.
46
XML Productivity Features
Mappings between tags and run-styles
FIGURE 32
Styles-to-tags user interface
Once a style-to-tag mapping has been defined and applied, then ranges of styled text that has
the styles referenced will be tagged. Note that there are some default commitments in terms of
the tags applied; for instance, the tag “Story” is used for a story, even if this is not present in the
tag-list of the document at the time of applying the style-to-tag mapping.
FIGURE 33
Structured document after mapping styles to tags
Design
The tag-to-style map is an associative mapping stored in workspaces (kDocWorkspaceBoss) or
kWorkspaceBoss). It is stored in the data interface IXMLTagToStyleMap on the workspace
boss classes, and changed via the facade interface IXMLMappingCommands.
XML Productivity Features
47
XML Productivity Features
Mappings between tags and run-styles
FIGURE 34
Structural diagram for tag-to-style map
«boss class»
kDocWorkspaceBoss
1
IXMLTagToStyleMap::GetTagAt
IXMLTagToStyleMap
1
IXMLTagToStyleMap::GetStyleMappedToTag
0..*
0..*
«boss class»
kXMLTagBoss
«boss class»
kStyleBoss
IXMLTag
«boss class»
kWorkspaceBoss
IXMLTagToStyleMap::GetTagAt
1
This is an associative mapping
from a tag (kXMLTagBoss)
to style (kStyleBoss)
IStyleInfo
IXMLTagToStyleMap
IXMLTagToStyleMap::GetStyleMappedToTag
1
0..*
0..*
«boss class»
kXMLTagBoss
A document workspace
(kDocWorkspaceBoss)
and the session workspace
(kWorkspaceBoss)
store a tag to style mapping
in the persistent
interface IXMLTagToStyleMap.
IXMLTag
«boss class»
kStyleBoss
A style (kStyleBoss) can
be a character style
or a paragraph style.
IStyleInfo
The tags (kXMLTagBoss) are also
referenced via the tag list (IXMLTagList)
on the workspace boss classes.
The tags referenced by the tag-to-style
map (IXMLTagToStyle) are a subset of
those in the tag-list.
The model for mapping styles-to-tags is symmetric with the model for mapping styles to tags.
It is shown in the figure entitled “Structural diagram for tag-to-style map” on page 48.
48
XML Productivity Features
Mappings between tags and run-styles
FIGURE 35
Structural diagram for style-to-tag map
«boss class»
kDocWorkspaceBoss
1
The workspaces maintain an
associative mapping, the associations
consist of UID-pairs, the LHS being
the UID of a style (kStyleBoss) and the
RHS being the UID of a tag (kXMLTagBoss).
This is stored in the persistent interface
IXMLStyleToTagMap.
IXMLStyleToTagMap
1
IXMLStyleToTagMap::GetStyleAt
IXMLStyleToTagMap::GetTagMappedToStyle
0..*
0..*
«boss class»
kStyleBoss
«boss class»
kXMLTagBoss
IStyleInfo
«boss class»
kWorkspaceBoss
1
IXMLStyleToTagMap::GetStyleAt
IXMLTag
IXMLStyleToTagMap
1
IXMLStyleToTagMap::GetTagMappedToStyle
0..*
0..*
«boss class»
kStyleBoss
«boss class»
kXMLTagBoss
IStyleInfo
Styles (kStyleBoss) can
be paragraph or character
styles
IXMLTag
The tags are also referenced
from each workspace via
the tag-list (IXMLTagList).
However, only those that
participate in the style-to-tag
mapping are linked via the
association maintained by
IXMLStyleToTagMap
Creating and modifying the mapping from tag to run-style
This mapping is stored in the interface IXMLTagToStyleMap on the document workspace
(kDocWorkspaceBoss) and session workspace (kWorkspaceBoss). It can be changed from
your code through methods on the command facade IXMLMappingCommands, on
kUtilsBoss.
Under the hood, modifying the tag-to-style map processes low-level commands like
kXMLMapTagToStyleCmdBoss, kXMLUnMapTagToStyleCmdBoss; see the table entitled
XML Productivity Features
49
XML Productivity Features
Mappings between tags and run-styles
“Low-level command notification details” on page 87 for details on how to observe
notifications sent by these commands.
See <sdk>/source/sdksamples/codesnippets/SnpPerformXMLTagAndStyle.cpp for an
example of using these low-level commands in context.
Creating and modifying the mapping from run-style to tag
This mapping is stored in the interface IXMLStyleToTagMap on the document workspace
(kDocWorkspaceBoss). It can be changed from your code through methods on the command
facade IXMLMappingCommands, on kUtilsBoss.
Under the hood, changing the style-to-tag map can result in the low-level commands such as
kXMLMapStyleToTagCmdBoss, kXMLUnMapStyleToTagCmdBoss being processed; see the
table entitled “Low-level command notification details” on page 87 for details on how to
observe notifications sent by these commands.
See <sdk>/source/sdksamples/codesnippets/SnpPerformXMLTagAndStyle.cpp for an
example of using these low-level commands in context.
Applying a mapping
Even if you have added new associations to the mapping between tags and styles, the document
would not appear to be any different; you need to apply the mapping to the document. At
present you need to process a low level command to do this.
The low-level command kXMLApplyTagToStyleMappingCmdBoss can be processed to apply
a tag to style map to a document. See the SDK sample named XDocBookWorkflow for an
instance of this command being processed in context.
FIGURE 36
Applying tag to style map
// Assume you have a reference to a document, IDocument*
InterfacePtr<ICommand> cmd(
CmdUtils::CreateCommand(kXMLApplyTagToStyleMappingCmdBoss));
cmd->SetItemList(UIDList(document));
CmdUtils::ProcessCommand(cmd);
Alternatively, you might copy the mapping from your own custom boss object with an
IXMLTagToStyleMap interface via the command facade IXMLMappingCommands.
At the time of writing there is no corresponding low-level command to apply a style-to-tag
mapping. At the time of writing, this is done by copying a mapping stored in an instance of a
dialog boss class (kStyleToTagMappingDialogBoss) to the workspace. If you wanted to
automate style-to-tag mapping, then you would have to define a class that aggregated
IXMLStyleToTagMap and then use IXMLMappingCommands to copy a mapping from an
instance of this class to a document workspace.
50
XML Productivity Features
Changing logical structure
Changing logical structure
Feature description
The logical structure is also changed when importing XML (see “Importing XML” on page 35)
or when applying a style-to-tag map (see “Creating and modifying the mapping from run-style
to tag” on page 50).
The logical structure is also changed when content items are tagged; for instance, see the use
cases “Tagging placeholder graphics frame for an image” on page 53 and “Tagging text and
graphics” on page 60. The logical structure can also be changed directly, e.g. by an end-user,
through the structure-view, or programmatically; elements can be created that are not
associated with content items as “structural elements”; see “Adding structural elements” on
page 54.
Changing logical structure by tagging content
To tag a placeholder item, the end-user creates a graphics frame, e.g. with the Rectangle tool,
and then chooses a tag to apply to this frame; for instance, they might tag it with “Image” to
indicate that the frame was to be populated with image-based content.
When a document object such as a graphic frame is tagged, then a new element is created in
the logical structure. There are two decisions that need to be made;
1.
what the parent of the new element should be,
2.
where the new element should be in the ordered collection of siblings of its new parent.
This section defines some of the rules that are used to decide where in the element tree a new
element is placed. Consider the case of tagging a graphic frame as a placeholder.
1.
If there are no tagged objects in the document, then a new element is created that is a
child of the root element.
2.
If there are already tagged objects in the document, then a new element is created that is
the last sibling of the root element.
The logical structure can be re-ordered either through the user-interface or programmatically,
through command facades like IXMLElementCommands.
It is also possible to add a new unplaced element anywhere into the logical structure using
either the structure-view user-interface, or using IXMLElementCommands. This can then be
associated with a document object using either a gesture, or programmatically.
In most cases, the document model does not constrain the logical structure; an exception is in
the case of tagging a text range, which requires the containing story (kTextStoryBoss) be
tagged. The element that is associated with the tagged text range is added a child of the element
in the structure that is associated with the tagged story.
An end-user can create a new element in the logical structure by executing the menu item
“New element” on the Structure pop-out menu on the Structure View window. The behaviour
of this menu item is not straightforward, since different behaviour results depending on
XML Productivity Features
51
XML Productivity Features
Changing logical structure
whether the element in the structure-view is already placed, and if placed what the associated
content item is. The following scenarios can be identified below.
1.
The root element is selected in the structure view, and the user executes the “New
element” menu item.
FIGURE 37
Before adding new element
In this case, the application adds a child element to the logical structure’s root element.
The child element by default is added at the end of the collection of child elements of the
root element. For example, the root element ‘book’ in the figure entitled “Before adding
new element” on page 52 is selected and a new element ‘article’ is added. The new
element is inserted into the logical structure as the last child of the root element and it is
shown as unplaced content, since the top level element was not placed; only its child
elements are placed content.
FIGURE 38
52
After inserting new element
2.
There is a selection in the structure view window that is an element mapped to a story
(kTextStoryBoss), and the user executes the “New element” menu item. This results in
the user creating a element in the logical structure which is associated with a text range in
the story except that the text range is of zero-length. The element is shown as placed,
because it has an association with story content, albeit an empty text range.
3.
There is an element selected in the structure view window associated with a graphic
placeholder frame and the user executes the “New element” menu item. This creates an
element that is a child of the selected element; however it has the net effect of turning the
XML Productivity Features
Changing logical structure
graphic frame into a text frame. That is, creating a new element in the structure-view
window when the element selected represents a graphic frame has the effect of turning
the graphic frame into a text frame. The object that stores the reference to the new
element in the structure view is a story (kTextStoryBoss). So the “New element” action in
this case has the net effect of tagging a story, which is as if the user had clicked in the
graphic frame with the text tool to convert its type.
4.
If there is an unplaced image element selected in the structure view is already an image,
e.g. has the default “href ” attribute that references a path in the local file system, then
there is a warning about turning the graphic frame into a text frame. If the element in the
structure view represents an image that is already placed, then the end-user can’t execute
“New element” anyway.
FIGURE 39
Turning an unplaced image into a text element
The “New element” option is unavailable when there is a layout selection, when there is a nonempty text selection, or when there is already a placed image in the structure view.
An end-user can add an element to the logical structure in either the structure view, in which
case the element is not directly associated with document content, or in another view such as
the document layout, by tagging some content item; for instance, a text range or a graphic
placeholder frame. See the associated use cases “Tagging placeholder graphics frame for an
image” on page 53 and “Tagging text and graphics” on page 60.
Tagging placeholder graphics frame for an image
FIGURE 40
Minimal XML content to place an image
<?xml version="1.0" encoding="UTF-8" ?>
- <Root>
<Image href="file://testfile.tif" />
</Root>
The example in the figure entitled “Minimal XML file to be imported” on page 17 shows an
example of XML for importing an image by reference. On importing the XML file, if we do not
have a pre-existing placeholder graphic frame tagged with “Image”, the image would not be
placed.
XML Productivity Features
53
XML Productivity Features
Changing logical structure
FIGURE 41
Unplaced image
If there is a pre-existing graphic frame tagged “Image”, then the image would be placed on
import. One constraint is that if you intend an image to be placed in the graphic frame, then
the element “Image” (for this example) must support the attribute “href ” that on import
should specify the system path to locate the image to be placed, or you will have to do extra
work to place the image yourself.
FIGURE 42
Placed image
You can customize the XML import to support placing images that are referred to by different
means; for instance, the sample XDocBookWorkflow places images based on an attribute
named “fileref ” (from DocBook). You could also customize this using the XSL transform
feature, described in “Walkthrough: transforming imported XML with XSLT” on page 70, or
using a custom SAX content handler, described in “Custom SAX Content handler” on page 75.
Adding structural elements
An end-user can add new elements to the logical structure of a document using the structureview and its associated pop-out menu. Elements created in this way are not immediately
associated with content items and are therefore unplaced. However, unlike content that has
been imported, there is no content associated with these elements when they are created.
You might be wondering why this is a significant use case; one reason that an end-user might
create elements in this way would be for creating “structural” elements that specified the
logical structure of a document and provided placeholders into which content could be placed.
FIGURE 43
Creating elements as structural elements
For instance, suppose that the content model for your publication is as a collection of
“Section” elements (e.g. Arts, Motoring etc.), but that each “Article” is worked on
independently in the editorial system, and imported/placed one at a time into the correct
section. You might have an element “Section” that consisted of a set of “Article” elements; the
“Section” element might never itself have any content but be used to structure the collection of
Article elements. The XML template for this publication might be set up as shown in the figure
entitled “Creating elements as structural elements” on page 54. Note that the Article elements
54
XML Productivity Features
Changing logical structure
show as placed content because these have been associated with linked text frames, but these
are placeholders into which the XML-based articles would be imported, with a top-level
element of Article.
To create new elements in the logical structure as an end-user, a selection is required in the
structure-view to indicate the element that is parent of the newly created element.
Design
Taggability
The suite named IXMLTagSuite can be used to tag a selection, such as a placeholder graphic
frame. The precondition is that the target of the selection can be tagged, which is relatively
complex to evaluate.
The utility interface IXMLUtils has a method IsTaggablePageItem that allows client code to
determine whether a given boss object can be tagged. There is also a method on IXMLUtils
named GetActualContent, which lets client code acquire a reference (UIDRef) to the
underlying boss object supporting the tagging operation. This is an instance of a boss class that
aggregates IXMLReferenceData.
XML Productivity Features
55
XML Productivity Features
Changing logical structure
Tagging graphics
FIGURE 44
«boss class»
kSplineItemBoss
Structural diagram for tagging placeholder item
IGraphicFrameData
IHierarchy
Backing store
1
«helper class»
XMLReference
Instantiate()
IHierarchy::GetChildUID
0..1
«boss class»
kTextXMLElementBoss
IIDXMLElement
1
IIDXMLElement::GetTagUID
0..1
«boss class»
kPlaceHolderItemBoss
1
1
IXMLReferenceData
«boss class»
kXMLTagBoss
Represents the name of tag and
colour of the tag as it appears in the UI.
When a graphic frame is created as
a target for content, e.g. an image,
it initially has a dependent that is an
instance of kPlaceholderItemBoss.
This disappears once content is placed,
becoming e.g. kMultiColumnItemBoss or
kImageItem or whatever, depending on
the type of content that is placed
A basic XML-related use case is tagging a placeholder graphic frame (see “Tagging placeholder
graphics frame for an image” on page 53. When an XML tag is applied to a graphic frame with
placeholder content, e.g. kSplineItemBoss with a kPlaceHolderItemBoss, then a new instance
of the class kTextXMLElementBoss is created and a link created between this object and the
boss object representing the placeholder item (kPlaceHolderItemBoss). This association is
shown in the figure entitled “Tagging placeholder graphics frame for an image” on page 53.
When an end-user tags a graphic frame as a placeholder, the structure-view draws a cross
through the icon representing the element, to indicate its placeholder status.
Client code can implement this using IXMLTagSuite::SetTag when there is a layout selection
set; for instance, you can create one programmatically with ILayoutSelectionSuite. See also
IXMLElementCommands::CreateElement methods, which are a facade onto the underlying
low-level commands that create the new objects in the logical structure, change the native
document model and create associations between the logical structure and the native
document model.
56
XML Productivity Features
Changing logical structure
Tagging text
It is not possible to “tag a text frame” with InDesign CS in a meaningful way. When the enduser makes a gesture to tag a text frame, the net result is that the user tags the story
(kTextStoryBoss) that flows through the frame. There are scenarios that make an end-user
believe that they have tagged a text frame, and the end-user (help) documentation mentions
tagging a text frame; however, you should always hold in mind that the story is the target for
the tagging operation. Consider the following scenarios:
1.
creating a text frame with the text tool, changing to the pointer tool and selecting the
empty text frame, then applying a tag
2.
creating a text frame with the text tool, leaving the insertion point in the newly created
text frame, then applying a tag
3.
creating a text frame with the text tool, entering text, selecting all the text in the frame
through a select-all gesture, then applying a tag
Although an end-user may believe that they are tagging a text frame, which is a layout object
that is a container for text, in reality, in each of the above scenarios, they are tagging the story
(kTextStoryBoss) that flows through the text frame.
Consider the scenario (2) where there is an insertion point an un-tagged frame and a user
wants to apply a tag, which they think is being applied to the text frame. In this case, the text
frame might be represented by a kSplineItemBoss, with its first child a
kMultiColumnItemBoss, and its first child in turn a kFrameItemBoss. Note that none of these
boss classes aggregate IXMLReferenceData and therefore cannot be associated with an element
in the logical structure. A boss class participating in the text frame model that can be associated
with an element in the logical structure is the story, kTextStoryBoss.
Scenario (3) is similar to scenario (2), except that (2) is a degenerate case where a zero-length
story is “selected”.
An end-user can select a text range and apply a tag to mark-up the text range. At the time of
writing, the following text ranges cannot be tagged:
1.
table cell text,
2.
inlines; graphics, notes, tracked changes, table frames, hyperlinks. See boss classes that
aggregate IOwnedItem,
3.
Ruby text annotations in Japanese,
4.
text in locked stories (see ITextLockData, InCopy Bridge).
If the text frame where the text selection exists is not associated with an element in the logical
structure, the end-user is prompted with a slightly misleading “Tag frame” dialog. In reality
the element that is chosen is associated with the story (kTextStoryBoss).
XML Productivity Features
57
XML Productivity Features
Changing logical structure
FIGURE 45
Tagging a range of text
A tag is applied to a text range by an end-user by making a text selection, and then either
clicking in the Tags panel on a particular tag, or selecting an item from a context-sensitive
menu containing the names of the tags. Once the range is tagged, tag markers are placed before
and after the tagged range. An example is shown in the figure entitled “Tagging a range of text”
on page 58. The [ and ] characters are non-printing, zero-width spaces inserted into the text,
which can be shown or hidden. Note that in this example, the tag “article” has been applied to
the story, and “emphasis” to the text range containing the characters “tagged”.
FIGURE 46
Tagged text range
K4EXT8-,%LEMENT"OSS
K4EXT3TORY"OSS
K8-,4AG"OSS
K3PLINE)TEM"OSS
K-ULTI#OLUMN)TEM"OSS
K&RAME)TEM"OSS
Consider the minimal example of tagging a text range, shown in the figure “Tagged text range”
on page 58. Of the classes shown (kSplineItemBoss, etc.) that participate in the native
document model, only kTextStoryBoss aggregates IXMLReferenceData. Although the enduser is shown a dialog to choose a tag for the text frame when they try to tag a range, the tag is
really applied to the story (kTextStoryBoss).
The boss class kTextStoryBoss represents a flow of styled text, as well as having special
responsibilities as the owner of the backing store (kSBOSPageBoss). When a story is tagged,
the IXMLReferenceData interface on the story (kTextStoryBoss) is populated with a reference
an object (kTextXMLElementBoss) in the logical structure.
58
XML Productivity Features
Changing logical structure
FIGURE 47
Structural diagram for tagging a story
Obtain instance of XMLReference
from IXMLReferenceData to
navigate from content item
to object representing element
in the logical structure
If a story has been tagged then the
interface IXMLReferenceData will refer
to the element that is the root of the
logical structure within the story
«helper class»
XMLReference
Instantiate()
Backing store
«boss class»
kTextStoryBoss
0..1
1 IXMLReferenceData
0..1
IIDXMLElement::GetContentItem
«boss class»
kTextXMLElementBoss
1
IIDXMLElement
1
IIDXMLElement::GetTagUID
1
«boss class»
kXMLTagBoss
IXMLTag
The story (kTextStoryBoss) in which the text range is contained must be tagged before a range
of text can be tagged; this creates an association of the kind shown in “Structural diagram for
tagging a story” on page 59.
The logical sequence of events when tagging a text range in an un-tagged story is:
1.
the story (kTextStoryBoss) is tagged. This involves creating an instance of
kTextXMLElementBoss in the root backing store (see “Backing store” on page 84) to
represent an element in the logical structure. In the example shown in the figure “Tagged
text range” on page 58, the root element has the tag “article”.
2.
An instance of kTextXMLElementBoss is created in the story’s own backing store to
represent an element in the logical structure. In the example above, this is the “emphasis”
element. Characters are inserted into the text model to represent the start and end of the
tagged text range. These are represented in the API by kTextChar_ZeroSpaceNoBreak
[see the SDK header file named public/includes/TextChar.h].
XML Productivity Features
59
XML Productivity Features
Changing logical structure
3.
The instance of kTextXMLElementBoss created to represent the element associated with
the text range tagged stores the start and end of the text range. The data stored can be
accessed through methods like IXMLUtils::GetElementIndices().
The use case is described in the section “Tagging text and graphics” on page 60.
Structural elements
When creating elements in the logical structure that are not based on importing external
content and are not immediately associated with content items in the document, the elements
are added to the backing store containing the parent element. When the parent is the root
element, then the root backing store would contain the newly created elements.
The design for creating elements unplaced in the logical structure is the same as that for
“Structural diagram for tagging placeholder item” on page 56, with the exception that there is
no initial association with a content item. In other words, IIDXMLElement::GetContentItem
would return kInvalidUID for the newly created elements.
Creating, updating and deleting elements and attributes
One way to add and remove elements from the logical structure is to use the suite interface
IXMLNodeSelectionSuite to program a selection in the structure-view, and then
IXMLStructureSuite, which acts on a selection in the structure view.
The command facade IXMLElementCommands provides methods (CreateElement overloads)
to create a new element in the logical structure not associated with a content item. It also
provides a method (DeleteElementAndContent) to delete elements in the logical structure.
Removing an element associated with placed content means that the corresponding layout
items may be deleted.
Under the hood, when an element is created, the low-level command
kXMLCreateElementCmdBoss is processed, and when it is deleted, the low-level command
kXMLDeleteElementCmdBoss is processed. See the table “Low-level command notification
details” on page 87 for more details on how to observe these operations taking place.
You can move elements in the logical structure using methods on IXMLElementCommands,
and you can also place elements from the logical structure using methods on this interface.
Moving elements in the logical structure may affect the native document model; however you
can make some changes in the logical structure without affecting the native document model.
For instance, if you have two stories that are tagged, then re-ordering the elements
corresponding to the two stories does not affect the native document model, only the logical
structure.
Creating, updating and deleting attributes can be done using methods on
IXMLAttributeCommands.
Tagging text and graphics
A text range can be tagged programmatically using the interface IXMLElementCommands,
aggregated on kUtilsBoss; this creates an instance of the class kTextXMLElementBoss for each
tagged range. To tag a text range or a story (kTextStoryBoss) programmatically, there are
60
XML Productivity Features
DTD and validation
CreateElement methods on the command facade IXMLElementCommands (on kUtilsBoss)
that can be used.
There are methods on the utility interface named IXMLUtils that allow you to determine the
element associated with a range of tagged text, once a tag has been applied.
You can tag a graphic frame as a placeholder for an image programmatically using
IXMLElementCommands; look for the methods that have the parameter “UID contentItem”
in their method signature. You can also use the interface IXMLTagSuite if there is a selection in
the structure-view, which you can create programmatically with IXMLNodeSelectionSuite.
See <sdk>/source/sdksamples/codesnippets/SnpPerformXMLElements.cpp for code that tags
content items. You should also see the SDK sample XMLMarkupInjector in the folder
<sdk>/source/sdksamples/xmlmarkupinjector, which tags text-ranges in non-trivial ways.
DTD and validation
Feature description
An end-user can import a DTD to create an association between the DTD and the document
logical structure, using the pop-out menu on the Structure panel. This associates the DTD with
the logical structure of the document. This also has the net effect of creating new tags in the
tag-list for elements defined in the logical structure; see “Tags and the tag-list” on page 41. At
the time of writing (InDesign CS), this does not create tags for those elements defined within
entities in the DTD.
FIGURE 48
Tags added after importing DTD
The figure entitled “Tags added after importing DTD” on page 61 shows tags created by
importing a DTD, in this case the example shown in “Basic grammar for article-based
publications” on page 89. Note how a visual indicator appears beside the tags created by
importing the DTD (article, article-title etc.).
XML Productivity Features
61
XML Productivity Features
DTD and validation
FIGURE 49
Validation error screenshot
An end-user can validate the logical structure of a document against a DTD once they have
associated a DTD with it. This results in any validation errors being shown in a window below
the structure-view; see the figure entitled “Validation error screenshot” on page 62. This
contains hyperlinks; if the end-user clicks on these hyperlinks, InDesign CS can automatically
fix the validation errors, although this may not always have the desired effect (for instance, it
may delete content that was incorrectly tagged given the grammar).
At the time of writing, the API does not support validating the logical structure of an InDesign
CS document against an XML schema [http://www.w3.org/TR/xmlschema-0/].
Design
A DTD associated with the logical structure of a document is represented by the class
kXMLDTDBoss. It is responsible for maintaining an association with a collection of tag objects
(kXMLTagBoss). These kXMLTagBoss objects are created with the names of elements defined
in the grammar, at least those that are defined outwith entities.
62
XML Productivity Features
DTD and validation
FIGURE 50
Structural diagram involving DTD element
«boss class»
kTextStoryBoss
Instance of non-user
accessible story that
owns the backing store
1
owns
1
«boss class»
kSBOSPageBoss
Root backing store for
the document
1
hasDTD
0..1
tags
«boss class»
kXMLDTDBoss
1
«boss class»
kXMLTagBoss
1..*
No public API to
this class of interest
The class responsible for the behaviour
of the DTD element is associated with the
set of tags (kXMLTagBoss) for the elements
defined in the DTD
Associate DTD
You can associate a DTD with a document by processing a low level command (an instance of
the class kXMLLoadDTDCmdBoss). See the figure entitled “Associating a DTD with a
document” on page 63.
Associating a DTD with a document has the effect of creating another element in the root
backing store for the document, an instance of class kXMLDTDBoss.
FIGURE 51
Associating a DTD with a document
InterfacePtr<ICommand> loadDTDCmd(CmdUtils::CreateCommand(kXMLLoadDTDCmdBoss));
InterfacePtr<IXMLLoadDTDCmdData> loadDTDData(loadDTDCmd, UseDefaultIID());
loadDTDData->Set(sysFile, document);
ErrorCode err = CmdUtils::ProcessCommand(loadDTDCmd);
Validate against DTD
There are two main ways to validate the logical structure of a document against a DTD:
XML Productivity Features
63
XML Productivity Features
Processing instructions and comments
1.
Use the action manager (IActionManager) to perform the equivalent action to when the
corresponding Structure menu item is executed (kStructureValidateRootActionID to
validate from the root, for instance).
2.
You can validate the logical structure using the suite interface IXMLStructureSuite,
which has methods relating to validation.
The ActionID for the action to validate the entire logical structure from the root is
kStructureValidateRootActionID. See source/public/includes/XMediaUIID.h for this and
related identifiers. Code that would perform this is shown in the figure “Validating the logical
structure” on page 64.
FIGURE 52
Validating the logical structure
// Assume that you have an activeContext (IActiveContext*) on entry
InterfacePtr<IApplication> theApp(gSession->QueryApplication());
InterfacePtr<IActionManager> actionMgr(theApp->QueryActionManager());
actionMgr->PerformAction(activeContext,
kStructureValidateRootActionID);
The suite interface IXMLStructureSuite offers methods CanValidateSelection (you should test
this precondition) and ValidateSelection. The method ValidateSelection requires you to take
responsibility for handling (e.g. displaying) the errors discovered on validation. To execute this
method, you need to supply an IXMLValidator interface pointer, which is a reference to the
boss object (kXMLDocumentBoss) responsible for performing the validation and storing the
results. To acquire the interface IXMLValidator (on kXMLDocumentBoss) you would write:
InterfacePtr<IIDXMLElement> docElement(Utils<IXMLUtils>()->QueryDocElement(db));
InterfacePtr<IXMLValidator> xmlValidator(docElement, UseDefaultIID());
When the validation has run, the interface IXMLValidator can be used to access to a collection
of instances of XMLDTDValidationError containing information about the errors.
Processing instructions and comments
Feature description
XML comments (see [http://www.w3.org/TR/REC-xml#sec-comments]) can appear anywhere
inside a document, outside of other mark-up. They can also appear inside the document type
declaration at places allowed by the grammar for defining a DTD. For instance:
<!-- This is a comment -->
Processing instructions (see [http://www.w3.org/TR/REC-xml#sec-pi]) allow XML-based
documents to contain instructions for applications that process them. XML-capable
applications like Adobe FrameMaker (in structured mode) use processing instructions to
preserve specialised types of content in XML documents. For instance:
<?FM MARKER [Index] translating, PIs?>
is a PI generated by FrameMaker on export to specify an index-term with the text “translating,
PIs”. It is possible to create new processing instructions anywhere within the logical structure.
64
XML Productivity Features
Processing instructions and comments
FIGURE 53
Processing instruction in the structure-view
An end-user can add XML-comments and processing instructions to the logical structure if
there is a selection in the structure-view.
Design
The backing store that is used
depends on where in the logical
structure the comment or processing
instructions are to be created.
«boss class»
kTextStoryBoss
1
If they are immediate children of the root
or in an unplaced hierarchy starting from
the root, then they would be present
in the root backing store.
owns
1
Otherwise they would be found in the backing
store associated with their parent element.
«boss class»
kSBOSPageBoss
stores
1
1
stores
0..*
0..*
«boss class»
kXMLCommentBoss
IStringData
This data interface stores
the text of the comment
«boss class»
kXMLPIBoss
IStringData (IID_IXMLPITARGET)
IStringData (IID_IXMLPIDATA)
These data interfaces store the
processing target (e.g. "FM") and
the data for the instruction
respectively.
XML comments are represented by the class kXMLCommentBoss. The IStringData interface
of this class is responsible for storing the text of the comment.
Processing instructions are represented by the class kXMLPIBoss; a processing instruction
appears to the user as a key-value pair {target, data}. There are two IStringData interfaces on
this class, which represent the processing target (IID_IXMLPITARGET) and the data for the
instruction (IID_IXMLPIDATA).
XML Productivity Features
65
XML Productivity Features
User interface
Adding comments and processing instructions
You should determine if it is possible to add a new comment given the selection in the
structure-view with IXMLTagSuite::CanAddComment.To create a new XML comment, you
can use IXMLTagSuite::AddComment. Under the hood, this processes the low-level command
kXMLCreateCommentCmdBoss, creating an instance of kXMLCommentBoss at the
appropriate location in the logical structure. See the table entitled “Low-level command
notification details” on page 87 for information on observing this command being processed.
To create a new processing instruction, you can use AddProcessingInstruction on
IXMLTagSuite. Under the hood, this processes the low-level command
kXMLCreatePICmdBoss to create a new instance of the boss class kXMLPIBoss in the logical
structure. See the table entitled “Low-level command notification details” on page 87 for
information on observing this command being processed.
There are other methods on IXMLTagSuite that allow you to change the key-value pair stored
with a processing instruction or delete the processing instruction.
User interface
Feature description
FIGURE 54
Structure-view: showing text snippets
The structure-view window creates a rendering of the logical structure of a document and lets
an end-user interact with the logical structure. It may be desirable to control the visibility and
other properties of this window, depending on your workflow.
Also since you can make selections within the structure-view programmatically (see “How do I
make a selection in the structure view?” on page 78), you may have a workflow that depends on
the view that supports this suite being active.
66
XML Productivity Features
User interface
Design
FIGURE 55
IXMLPreferences
Preferences relating to the structure-view
«boss class»
kWorkspaceBoss
IStructureViewPrefs
IDocStructurePrefs
«boss class»
kDocWorkspaceBoss
IDocStructurePrefs
The XML view-preferences are split
across the two workspaces.
The document-specific preferences, such
as whether the structure-view is on show for
a given document, are held in IDocStructurePrefs,
found on both session and document workspaces.
There are other session-level view preferences e.g.
whether to show text snippets (IStructureViewPrefs)
or whether to show tagged frames (IXMLPreferences)
There is an interface named IDocStructurePrefs that controls the properties of the structureview and the validation errors window, relating to whether they are visible.
There is a separate interface called IStructureViewPrefs that stores other properties the
structure-view window, such as whether text snippets are to be shown, as in the figure entitled
“Structure-view: showing text snippets” on page 66.
There is also an interface named IXMLPreferences on the session workspace
(kWorkspaceBoss) that determines the visibility of tag-markers and whether to show tagged
page items in a different colour to other page items.
Visibility of the structure-view
The approach that you can take is to ask the action manager (IActionManager) to perform an
action on your behalf (kOpenStructureWinActionID), which will process the low-level
command to change the preference relating to the structure-view window
(IDocStructurePrefs) and update the state of the structure-view window, showing the
structure-view if it is hidden and hiding the structure-view if it is showing. Despite the action
name, if the structure-view is already open before you execute this code, this will close it.
FIGURE 56
Processing action to toggle structure-view visibility
// Assume activeContext is a variable of type IActiveContext*
// referring to the active context
InterfacePtr<IApplication> app(gSession->QueryApplication());
InterfacePtr<IActionManager> actionManager(app->QueryActionManager());
actionManager->PerformAction(activeContext, kOpenStructureWinActionID);
There is a low-level command named kChangeDocStructurePrefsCmdBoss that changes the
preferences relating to the structure view window (IDocStructurePrefs); see “Preferences
relating to the structure-view” on page 67. However there is no public API to make it easy to
XML Productivity Features
67
XML Productivity Features
XSL support
translate changing these preferences into the action of showing/hiding the structure view.
These preferences are stored in both the session workspace (kWorkspaceBoss) and the
document workspace (kDocWorkspaceBoss) to customize the visibility of the structure-view
on a per document basis.
Appearance of the structure-view
Some structure-view preferences stored in IStructureViewPrefs (on the session workspace
only, kWorkspaceBoss); these control the appearance of the structure-view when it is visible.
The appearance is controlled by preferences stored in IStructureViewPrefs on the session
workspace (kWorkspaceBoss). You can change these in one of two ways:
1.
Ask the action manager (IActionManager) to perform the appropriate action.
2.
Process the low-level command that changes the data stored on this interface yourself.
For instance, to toggle the visibility of text snippets in the logical structure view, you can ask
the action manager to perform the action kStructureShowTextSnippetsActionID or process
the low-level command kChangeStructureViewPrefsCmdBoss and set up IStructureViewPrefs
on the command yourself to reflect your intent.
To perform the action kStructureShowTextSnippetsActionID, you would write code similar to
that in the figure“Processing action to toggle structure-view visibility” on page 67.
The method to process the low-level command would involve writing code like this:
FIGURE 57
Processing command to change structure-view appearance
InterfacePtr<IStructureViewPrefs>prefs( static_cast<IStructureViewPrefs*>(
::QueryPreferences(IStructureViewPrefs::kDefaultIID, kGetSessionPrefs)));
InterfacePtr<ICommand>cmd(
CmdUtils::CreateCommand(kChangeStructureViewPrefsCmdBoss));InterfacePtr<IStructureV
iewPrefs>cmdPrefs(cmd, UseDefaultIID());
cmdPrefs->Copy(prefs);
cmdPrefs->SetShowTextSnippets( !prefs->ShowTextSnippets() );
cmd->SetItemList( ::GetUIDRef(prefs) );
CmdUtils::ProcessCommand(cmd);
XSL support
Feature description
Since version CS, the applications can transform imported XML by applying an XSLT style
sheet; this only happens during the import process by default. This feature support workflows
where content for import can be represented in a variety of XML languages but a single XMLbased template is used throughout and the XML must be transformed on import to match the
grammar the XML-template expects.
68
XML Productivity Features
XSL support
Design
The service (with ServiceID of (kDataServices) that can transform an incoming XML file via
XSLT depends on an XSL enabler service (kXSLEnablerService) being available. The XSLT
transform is not applied if an XSL enabler service cannot be located.
You must implement your own XSL enabler service that turns on the XSL-transform feature;
see the section “Extension points” on page 73, since the application does not ship with this
service.
Transforming imported XML
To make the application transform imported XML via an XSL style sheet, you must:
1.
Make sure that you have provided an XSL enabler service.
2.
Process the low-level import XML file command yourself and set up the data interface
(IStylesheetData) on the import XML command to reference the XSL style that you want
to import.
The binding between the low-level command responsible for importing XML
(kImportXMLFileCmdBoss) and the XSLT transform is via a service provider with ServiceID
of kDataServices. This has the service interface named IDataServices, with a method
TransformContent. The transform can only happen if it can locate a service provider
kXSLEnablerService.
A code fragment setting up the IStylesheetData interface and processing the low-level import
XML file command is shown in the figure entitled “Setting the stylesheet for import” on
page 69, which imports the XML into the “context document” (from IActiveContext). This
will apply the transform in the style sheet if an XSL enabler service is available.
FIGURE 58
Setting the stylesheet for import
// Assume you have xmlSysFileToImport and stylesheetSysFile on entry, perhaps
// through using SDKOpenFileChooser to select them at some stage
InterfacePtr<ICommand> importCmd(
CmdUtils::CreateCommand( kImportXMLFileCmdBoss));
InterfacePtr<IImportFileCmdData> importCmdData(importCmd,
IID_IIMPORTFILECMDDATA);
importCmdData->Set(::GetDataBase(ac->GetContextDocument()),
xmlSysFileToImport,
kSuppressUI);
InterfacePtr< IStylesheetData> stylesheetData(importCmd, UseDefaultIID());
stylesheetData->SetFile(stylesheetSysFile);
CmdUtils::ProcessCommand(importCmd);
There is a rudimentary user-interface already in the application that can be invoked when
IXMLImportOptions is set up so that ShouldUseImportFilter() returns kTrue. This can be
done by processing the low-level command kChangeXMLImportOptionsCmdBoss.
A basic implementation of this is shown in the figure entitled “Changing XML import options”
on page 31; a better alternative would be to respect the existing options (by acquiring these
before processing the command and setting those on the data interface IXMLImportOption of
XML Productivity Features
69
XML Productivity Features
Walkthrough: transforming imported XML with XSLT
the command) and set only the UseImportFilter(). When the “Import XML” action is
executed, then a dialog appears which offers a control into which the platform path of the XSL
style sheet to use can be specified.
FIGURE 59
Setting XML import options to show import filter
// Assume ac is a variable of type IActiveContext* and valid on entry
IWorkspace* wkSpc = ac->GetContextWorkspace();
InterfacePtr<ICommand>
cmd(CmdUtils::CreateCommand(kChangeXMLImportOptionsCmdBoss));
InterfacePtr< IXMLImportOptions> importOptions(cmd, UseDefaultIID());
cmd->SetItemList(UIDList(wkSpc));
importOptions->SetImportIntoSelected(kTrue);
importOptions->SetImportStyle(IXMLImportOptions::kMerge);
importOptions->UseImportFilter();
Walkthrough: transforming imported XML with XSLT
An implementation that used this feature was carried out, where we took some standard but
fairly complex XML language and wrote a style sheet to map it into a simpler grammar on
import. A fragment of an NITF file [http://www.nitf.org/] is shown in the figure entitled “XML
fragment from NITF file” on page 70. This came from a file on the NITF site; you can find the
complete file at [http://www.nitf.org/IPTC/NITF/3.2/examples/nitf-fishing.xml].
FIGURE 60
XML fragment from NITF file
<body.content>
<media media-type="image" style="align:right">
<media-reference mime-type="image/jpeg" source="high-tide.jpg" alternate-text="The tides are high." he
</media-reference>
<media-caption>
The tides, captured on film late yesterday.
</media-caption>
<media-producer>
Karben
</media-producer>
</media>
<p xml:lang="en-US">The weather was superb today in Norfolk, Virginia. Made me want to take
out my boat, manufactured by the <org value="acm" idsrc="iptc.org">Acme Boat Company</org>.</p>
<p>Tides in Norfolk are running normal today. This weeks article highlights many of
this week's fishing issues, and also presents a reference table of tide times.</p>
<hl2>The Tides are High</hl2>
<p>As can be seen from the table below, the shores of Oceanview again present the
brightest spots for fishermen and sandcastle-builders alike.</p>
<nitf-table>
<nitf-table-metadata>
<nitf-table-summary>
<p>This is a table filled with weather data, good for fishermen
living in Norfolk, Virginia.</p>
</nitf-table-summary>
<nitf-col value="beach"/>
<nitf-col value="day-high"/>
<nitf-col value="day-low"/>
<nitf-col occurrences="2" value="tide-time"/>
The following steps were carried out as part of this implementation:
70
XML Productivity Features
Walkthrough: transforming imported XML with XSLT
1.
A basic grammar was defined (see “Basic grammar for publication composed of articles”
on page 32) and an instance of an XML file produced by this grammar generated
2.
A minimal XSL style sheet was written to map from NITF to our basic grammar with
little attempt to extract more than the minimum content.
3.
Tags were loaded into an InDesign CS document from the instance of the XML file
produced by our basic grammar
4.
Paragraph styles were set up matching the names of the tags in the basic grammar,
namely article-title, title, subhead, para, and a character style named “emphasis”.
A basic grammar was defined as a target language for transforming NITF into; see the figure
entitled “Basic grammar for article-based publications” on page 89. This grammar expresses
that a publication is composed of articles, composed of an ‘article-title’ and repetitions of the
elements title, subhead and para. No attempt is made in this basic example to cater for images
or tables, although the extensions required to support these are fairly apparent. See the section
“Defaults and constraints” on page 26 for suggestions on how to implement this.
The style sheet that was used to turn the NITF into XML conforming to the basic grammar is
shown in the figure “Fragment of XSL stylesheet to convert NITF to basic pub” on page 89.
The NITF grammar can be downloaded from [http://www.nitf.org/IPTC/NITF/3.2/dtd/nitf-32.dtd]. The document type declaration is documented at
[http://www.nitf.org/IPTC/NITF/3.2/documentation/nitf-documentation.html].
Tags were imported from an instance of an XML file generated from the basic grammar. An
XML template was set up with paragraph styles matching the tag styles. The low-level
command to import XML was processed, setting up the IStylesheetData as necessary to refer to
the XSL style sheet.
Some points to note about the XSL in the figure entitled “Fragment of XSL stylesheet to
convert NITF to basic pub” on page 89 are the use of normalize-space() to normalize the
white-space in the XML, and use the xsl:text to force line breaks on import so that InDesign CS
will apply the correct paragraph styles.
XML Productivity Features
71
XML Productivity Features
Walkthrough: transforming imported XML with XSLT
FIGURE 61
Result of importing transformed XML
An example of the output when the nitf-fishing.xml file in NITF was transformed on import
by InDesign CS is shown in the figure “Result of importing transformed XML” on page 72.
The example made no attempt to turn the NITF table into a tabular format and removed the
nitf-table element with an empty xsl:template. It would be fairly straightforward to respect the
table data and transform it into the aid:table content model, by adapting the style sheet at
[http://www.nitf.org/IPTC/NITF/3.2/examples/nitf-to-html.xsl]. See the use case “Importing a
table” on page 39 for more context.
72
XML Productivity Features
Extension points
Extension points
Custom suite for the structure-view
Suites are concerned with manipulating the properties of an abstract selection. A suite exposes
an interface that is written to be selection-format agnostic, which lets you work with an
abstract selection. It is possible to work either with the selection set by an end-user or
programmatically create a selection and then use suite interfaces to manipulate the properties
of the selection.
If you write a plug-in that interacts with the model behind a selection in any way, you must
implement a custom suite. That is, if you need to know (and manipulate) the target of a
selection, then you should implement a custom suite.
The design of the selection subsystem is already described in some detail in tech-note #10006
on the selection architecture. This material is not intended to rehearse or replace that content,
and presumes that you are familiar with that material.
If you do not know how to implement a custom suite or what it signifies, then see the selection
tech-note (#10006) for clarification. From this point onwards, it is assumed that you are
familiar with implementing a custom suite.
FIGURE 62
Custom suite for the structure-view
ASB
«boss class»
kIntegratorSuiteBoss
You need to provide implementations
of your interface on the "abstract"
suite boss (kIntegratorSuiteBoss)
and the "concrete" suite boss (in
this case kXMLStructureSuiteBoss).
IYourCustomSuite
CSB
«boss class»
kXMLStructureSuiteBoss
IYourCustomSuite
IXMLNodeTarget
If you wanted to implement your own custom suite that was available whenever there was a
selection in the structure-view, then you would need to follow the pattern of
IXMLStructureSuite, and add-in your custom suite to both kIntegratorSuiteBoss (ASB in
terms of the selection architecture) and kXMLStructureSuiteBoss (CSB).
You are not able to share (re-use) one implementation of your suite interface for the add-ins to
the different boss classes, because each implementation of your custom suite interface is tied to
one selection format. The implementation associated with the ASB is normally based on
templates in the API and the code is normally highly stereotyped. However, the
implementation added to any CSB that you are interested in works with a specific model
format, in this case, a node-set in the logical structure.
XML Productivity Features
73
XML Productivity Features
Extension points
For instance, suppose that you wanted to write a custom suite that verified the image
references in the nodes selected. When you implement a custom suite, it gives you access to the
nodes selected in the structure view. These are represented by IXMLNodeTarget. If you add-in
your custom suite to the CSB kXMLStructureSuiteBoss, then the interface IXMLNodeTarget
becomes available to your custom suite implementation code, at least, to the implementation
behind the interface you have added to the CSB. This is illustrated in the figure entitled
“Custom suite for the structure-view” on page 73.
XSL Enabler
FIGURE 63
XSL Enabler service provider
«boss class»
kYourCustomXSLEnablerServiceBoss
«interface»
IK2ServiceProvider
HasMultipleIDs ()
GetServiceID()
GetServiceIDs(out serviceIDs : K2Vector<ServiceID>)
«partial implementation class»
CServiceProvider
«interface»
IXSLEnabler
Enable()
Disable()
«implementation class»
YourCustomXSLEnabler
«partial implementation class»
YourCustomXSLEnablerSvcProvider
GetServiceID()
Should return a ServiceID of
kXSLEnablerService
No partial implementation
to assist, so use parameterized
type CPMUnknown to implement
An XSL enabler is a service provider that returns the Service ID of kXSLEnablerService. The
service interface that the service provider boss class should aggregate is IXSLEnabler.
The figure entitled “XSL Enabler service provider” on page 74 indicates your responsibilities
when implementing this category of service provider. Note that the classes that you are
required to provide have names that contain “YourCustom”.
74
XML Productivity Features
Extension points
To make this fully explicit, the service provider boss class would be defined in your FR file as
something like:
Class
{
kXMLBldBlkXSLEnablerServiceBoss,
kInvalidClass,
{
IID_IXSLENABLER,kXMLBldBlkXSLEnablerImpl,
IID_IK2SERVICEPROVIDER, kXMLBldBlkServiceProviderImpl,
}
},
where the string “XMLBldBlk” has replaced “YourCustom”.
Custom SAX Content handler
A custom SAX content handler lets you read your own content from an XML input stream and
take appropriate action. When the application reads an XML stream in importing an XML file,
it uses the SAX API [see http://sax.sourceforge.net/]. You can register as a handler for elements
in the input XML stream and you are responsible for parsing the element, and its sub-tree as
well if you choose.
FIGURE 64
Custom SAX content handler
«boss class»
kYourCustomContentHandlerBoss
«interface»
ISAXContentHandler
Register()
StartDocument()
EndDocument()
StartElement()
EndElement()
«partial implementation class»
CSAXContentHandler
«interface»
IK2ServiceProvider
This must have a ServiceID of
kXMLContentHandlerService.
Re-use the implementation
kXMLContentServiceProviderImpl,
of type IK2ServiceProvider
«implementation class»
YourCustomContentHandler
A SAX content handler is a service provider characterised by:
1.
the service interface ISAXContentHandler.
XML Productivity Features
75
XML Productivity Features
Extension points
2.
the signature interface IK2ServiceProvider. The ServiceID must be of type
kXMLContentHandlerService; you can re-use the API implementation
kXMLContentServiceProviderImpl (implementation of IK2ServiceProvider) to do this.
The pattern is shown in the figure entitled “Custom SAX content handler” on page 75. Note
that you are responsible for the classes whose name contains “YourCustom”. To make this
fully explicit, you would define a boss class similar to that shown below, where “YourCustom”
has been replaced by “XMLBldBlkCALS”.
Class
{
kXMLBldBlkCALSContentHandlerBoss,
kInvalidClass,
{
IID_IK2SERVICEPROVIDER, kXMLContentServiceProviderImpl,
IID_ISAXCONTENTHANDLER,kXMLBldBlkCALSContentHandlerImpl,
}
},
SAX content handlers are widely used by the application; see boss classes that aggregate the
interface named ISAXContentHandler. For instance, the service
kXMLTableContentHandlerBoss is responsible for turning content in an aid:table context into
a native InDesign CS table; see also “Importing a table” on page 39.
The example of the table content handler (kXMLTableContentHandlerBoss) illustrates
modifying the default XML-import behaviour of the application, when importing XML-based
content. You can also use a SAX content handler just to read XML-based data, without
creating elements in the logical structure and/or storing content in a backing store.
For instance, panels like the Swatches panel read their options, positions and so on from an
XML-file using a SAX content handler. The file “ActiveWorkspace.xml” in the preferences
folder for the application contains this XML-based data and is parsed by custom SAX content
handlers for each panel. The data is written to the XML file using custom XML generators
(IXMLGenerator) for each panel.
Custom tag service
A tag service is given the opportunity to handle elements in an XML stream that has been
opened for reading element names to be used as tags. Why would you want to implement a tag
service? For instance, you might have some custom content in the XML file that is created
programmatically on export and you do not want end-users to be able to apply the tags based
on the element names in your custom content.
There is an instance in the API of a tag service named kXMLTableTagContentHandlerBoss; it
is used to strip out the table-related tags when loading tags from an XML file. This is because
the elements representing a table are added programmatically on export by the application,
and end-users should not be able to apply these tags themselves.
A tag service is a service provider that is closely related to the SAX content handler service,
characterised by:
1.
76
the service interface ISAXContentHandler,
XML Productivity Features
Extension points
2.
the interface IK2ServiceProvider, which should yield a ServiceID of
kXMLTagHandlerService. You can re-use of the API implementation named
kXMLTagServiceProviderImpl to achieve this.
Since you are likely to be using this to filter out names of custom elements that you do not
want to appear in the tag-list, you have to provide a minimal implementation of
ISAXContentHandler that registers your handler for the elements you want to filter out and
claims to handle a sub-tree. You then need do nothing when sent the other
ISAXContentHandler messages.
Custom SAX entity resolver
A custom SAX entity resolver lets you customize entity resolution when a document type
(DTD) is being processed by the application’s XML parser. It requires you to not only define a
boss class aggregating an interface named ISAXEntityResolver, but you must implement a
custom command to associate the DTD with a document that replaces the default command
(kXMLLoadDTDCmdBoss) but provides equivalent behaviour.
InDesign CS does not, at the time of writing, support resolution of PUBLIC identifiers to
entities such as paths on a local file system. For instance, if you want to validate against the
DocBook DTD that makes extensive use of PUBLIC identifiers, you would need to implement
a custom SAX entity resolver.
In the use case “Associate DTD” on page 63, it was mentioned that you can process a
command of type kXMLLoadDTDCmdBoss to associate a DTD with the logical structure of an
application document.
Suppose that you want to work with a document type like DocBook, that uses public identifiers
in the DTD.
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd"
[...]>
By default InDesign CS will not support resolution of a public (external) identifier to a file
system identifier, and you will have to implement a custom entity resolver if you want to
import XML that depend on public identifiers being correctly resolved for your system. You
would also be responsible for writing a custom load DTD command that would let you replace
the default entity resolver used by the normal load DTD command to use your own custom
variant.
To create your own custom entity resolver, it is necessary to deliver a boss class that aggregates
the interface ISAXEntityResolver. See the class InCopyDocUtils (InCopyFileActions sample,
located in <sdk>/source/sdksamples/incopyfileactions) and the method GetStreamFileType.
This uses an instance of a boss class kXMLEmptyEntityResolverBoss to let InCopy, when
opening an InCopy XML story file, eliminate the normal behaviour of the default entity
resolver (kXMLEntityResolverBoss).
XML Productivity Features
77
XML Productivity Features
Frequently asked questions
Frequently asked questions
What is the difference between logical structure and the native document model?
The logical structure of an InDesign CS document is a tree-structure, consisting of a tree of
elements. An element in the logical structure is represented by a boss classes aggregating an
IIDXMLElement interface. See the section “Logical structure” on page 20.
The native document model for an InDesign CS document models an end-user’s document as
a hierarchy of objects; see “Native document model” on page 81. For instance, the native
document model represents spreads, spread-layers, pages, document layers and so on. It is
considerably more complex, even for an empty document, than the logical structure.
Elements in the logical structure are associated with tags, and can be associated with content
items in the native document model if they represent placed content or tagged placeholders.
See “Key associations” on page 24. Elements are held in a backing store; see “Backing store” on
page 84
It is possible to navigate through the logical structure via just the interface IIDXMLElement.
There is no single way to navigate through the native document model; e.g. interfaces such as
IHierarchy, ISpread, ISpreadLayer and others may be used for navigation.
The logical structure is rendered in the structure-view. The native document model is rendered
most completely in the layout view. Other renderings of subsets of the native document model
are possible (e.g. Story Editor view).
How do I make a selection in the structure view?
Suites are facades that make it easier to change the model from client code and represent a
“medium-level” API; see “Suites and utilities” on page 34. There are some suite interfaces that
can be used to make selections from client code; e.g. ITextSelectionSuite (make a text selection,
e.g. a text range within a story), ILayoutSelectionSuite (make a layout selection, e.g. of a
graphic frame). There is a corresponding selection suite in the XML subsystem. The interface
named IXMLNodeSelectionSuite can be used to select nodes in the structure-view. An instance
can be acquired from the selection manager (ISelectionManager) for the structure-view.
The interface IXMLNodeSelectionSuite allows you to select objects by XMLReference. This is
analogous, but not identical to, selecting objects in the layout view by UID. See the section
“Changing logical structure” on page 51 for more detail on working within the logical
structure tree. Read the tech-note on the selection architecture (#10006) for more information
on the selection subsystem.
One of the first problems that you will encounter in working with IXMLNodeSelectionSuite is
that you have to acquire the selection manager for the correct view; an end user of InDesign CS
typically works in the layout view and the selection manager for this view (on
kAbstractLayoutDocumentSelectionBoss ) does not know about IXMLNodeSelectionSuite.
The concept of a selection subsystem is tied to that of a view, and for each view, there is a
corresponding selection manager (ISelectionManager)
78
XML Productivity Features
Frequently asked questions
To use IXMLNodeSelectionSuite, you need to acquire the structure-view’s selection manager
(the ISelectionManager on kAbstractXMLSelectionBoss ). You need to be sure that the
structure-view is visible (see “Visibility of the structure-view” on page 67). If the structureview is visible, then you can acquire a reference to it by knowing the WidgetID for the panel it
contains (kXMLPanelWidgetID). A code fragment showing this is given in the figure entitled
“Using IXMLNodeSelectionSuite in the structure-view” on page 79. Note that nil interface-ptr
checking has been omitted, which in the general case would not be wise, as some of these could
be nil, for instance, if the structure-view is not shown.
FIGURE 65
Using IXMLNodeSelectionSuite in the structure-view
// Assume we have an active context, IActiveContext*
// Nil ptr checking is omitted in interests of brevity
IDocument* doc = activeContext->GetContextDocument();
InterfacePtr<IWindowList> list(doc, UseDefaultIID());
InterfacePtr<IPanelControlData> docPanelData(list->GetFrontWindow(),
UseDefaultIID());
IControlView* view = docPanelData->FindWidget(kXMLPanelWidgetID);
Utils<ISelectionUtils>()->ActivateView(view);
InterfacePtr<ISelectionManager>selectionMgr(
Utils<ISelectionUtils>()->QueryViewSelectionManager(view));
InterfacePtr<IXMLNodeSelectionSuite>
xmlNodeSelectionSuite(selectionMgr, UseDefaultIID());
InterfacePtr<IIDXMLElement> rootElement(
Utils<IXMLUtils>()->QueryRootElement(doc));
XMLReference rootRef = rootElement->GetXMLReference();
xmlNodeSelectionSuite->SelectElement(rootRef, Selection::kAddTo);
How do I create, update or delete elements in the logical structure?
One way to do this is to create a selection in the structure view programmatically and then use
the suite IXMLStructureSuite, which depends on a selection existing in the structure view. See
the FAQ “How do I make a selection in the structure view?” on page 78 for information on
how to make a selection in the structure view programmatically.
Once you have established a selection in the structure-view, then you can use suites such as
IXMLStructureSuite to modify the logical structure. The code fragment in the figure entitled
“Code fragment with IXMLStructureSuite” on page 79 shows in outline how this could be
done to add an element. To add an element, you need to provide a reference to the tag (by
UID) that represents the element’s tag-name. To find out how to create a tag, see the section
“Creating, updating and deleting tags” on page 45.
FIGURE 66
Code fragment with IXMLStructureSuite
// Let ‘doc’ be the document (IDocument*) in which we are working
InterfacePtr<IXMLStructureSuite> xmlStructureSuite(
static_cast<IXMLStructureSuite* > (Utils<ISelectionUtils>()->QuerySuite(
IXMLStructureSuite::kDefaultIID)));
if(xmlStructureSuite->CanAddElement ()) {
... create tag for element...
ErrorCode err = xmlStructureSuite->AddElement(UIDRef(::GetDataBase(doc),
createdTagUID));
...
XML Productivity Features
79
XML Productivity Features
Summary and conclusions
}
If for some reason you do not have a structure-view, e.g. you are working with “headless”
documents opened without a view onto them, then you cannot use the method of setting a
selection. However, you can still use IXMLElementCommands to create, update and delete
elements in the logical structure even when you do not have a view, as this does not depend on
having a selection. See “Changing logical structure” on page 51 for more information.
How can I read in some arbitrary XML content?
The most convenient way to do this is to implement a custom SAX content handler; see the
section “Custom SAX Content handler” on page 75. For instance, you might want to import
some XML-based content into the document such as a table defined in CALS table format,
which is not supported by InDesign CS without writing such an extension.
Alternatively, you might have configuration data expressed in XML; the palettes read their
positions and other properties through a custom SAX content handler.
How do I validate an XML document from within the applications?
You can associate a DTD with a document programmatically and then ask the applications to
validate the logical structure of the document against the DTD. See the section “DTD and
validation” on page 61
How do I change the XML import options?
Process the low-level command kChangeXMLImportOptionsCmdBoss; this changes the data
stored on the interface IXMLImportOptions. See also the section “Importing XML data” on
page 38
Summary and conclusions
This document has explored programming with the XML API of InDesign CS. Using XML in
conjunction with InDesign CS has some benefits for programmers, which include the
following:
80
•
It is relatively easy to pre-process XML for import into InDesign CS. There are numerous
mature XML-toolkits for diverse programming languages; see for instance
[http://xml.coverpages.org/software.html] for listings.
•
Importing graphics into tagged placeholders is a convenient way to place graphics
without writing very much, if any, code.
•
Importing tables from an XML data file is again a convenient way to import rich content
without having to write very much, if any, code
•
The XML API of InDesign CS is well-documented; in terms of interfaces at least, the
documentation is largely complete.
XML Productivity Features
Appendix
•
It is relatively straightforward to program with the XML API of InDesign CS, compared
to programming with the APIs that manipulate native document content. It is somewhat
easier to work within the logical structure of a document with tagged content than within
the native document model.
One often-quoted reason for using an XML-based workflow is for “cross-media publishing”.
Whilst this may be attractive in principle as a means of repurposing content for different
media, it is not clear how many mature workflows exist in the newspaper and magazine
industry that use XML in this way. However, there is a trend of increasing use of XML within
newspaper publishing. Wire-feeds are now available in XML vocabularies; NewsML
[http://www.newsml.org], NITF [http://www.nitf.org], and supported by systems integrators
and publishing systems vendors.
Solutions based on the XML features of InDesign CS might include the following:
1.
Automated production of catalogs and other publications that depend on database
content that has a defined schema. Mainstream database vendors are shipping “XMLaware” databases, that are able to wrap the results of queries in XML or store XML
documents to standard relational databases.
2.
Variable-data publishing (VDP) systems to create personalised marketing material and
other publications. Creating tagged placeholders for variable image content and tagged
text ranges for variable text would take away some of the pain from implementing a VDP
solution.
3.
Importing content from diverse datasources (e.g. wire-feeds in NewsML, data from a
relational database) that have different XML vocabularies into a uniform XML template
using the XSLT support of InDesign CS.
Appendix
Native document model
The native document model specifies how end-user documents are represented by InDesign CS.
An InDesign CS document is represented by a hierarchy of persistent boss objects. The root
node of a document is an instance of the boss class named kDocBoss.
The end-user conceptual model of an InDesign CS document would be a hierarchy of spreads,
master spreads, layers, pages, page items and so on. The underlying native document model
has classes that represent spreads (kSpreadBoss), pages (kPageBoss), page items
(kPageItemBoss).
Key boss classes from the native document model are shown in a structural diagram entitled
“Native document model, showing content items” on page 82, which indicates ownership
relationships. The diagram has been decorated to indicate which of the classes in the diagram
participate in the XML subsystem; with the exception of the class kDocBoss, which represents
the root node of the native document model, the classes highlighted each model content items
in the document, such as stories or images.
XML Productivity Features
81
XML Productivity Features
Appendix
FIGURE 67
Native document model, showing content items
Classes that can have an association with
elements in logical structure are highlighted.
These all represent content items. There are
others not shown, this is a sample.
Represents the root node of the
document.
The arrows indicate direction of
ownership
«boss class»
kDocBoss
«boss class»
kSpreadBoss
«boss class»
kMasterPagesBoss
«boss class»
kDocumentLayerBoss
«boss class»
kTextStoryBoss
«boss class»
kDocWorkspaceBoss
Spread
Represents master
spread
«boss class»
kSpreadLayerBoss
«boss class»
kPageBoss
Owns content,
guides, and
pages
Graphic
frame
Represents a flow of
styled text
Document layer
as seen in user
interface
«boss class»
kSplineItemBoss
«boss class»
Guide
kGuideItemBoss
Stores document-specific
options
«boss class»
kGroupItemBoss
Visual page
bounds
Represents a group
of layout objects
«boss class»
kMultiColumnItemBoss
«boss class»
kImageItem
Represents a placed
image, such as a JPEG
«boss class»
kFrameItemBoss
«boss class»
kPlacedPDFItemBoss
«boss class»
kEPSItem
Represents a placed
PDF
Represents a placed
EPS graphic
Column controller for a
text frame, contains one
or more column items
Represents single
column of text. Fundamental
visual container for text
Content items that can be tagged are identified by the interface IXMLReferenceData. Another
view of the native document model is shown in the figure entitled “Native document model
and XML-related interfaces” on page 83.
82
XML Productivity Features
Appendix
FIGURE 68
Native document model and XML-related interfaces
Root node of document model.
Has reference to the XML document
element (kXMLDocumentBoss) stored
in IXMLReferenceData interface.
«boss class»
kDocBoss
IXMLReferenceData
1
ISpreadList::GetNthSpreadUID
1..*
«boss class»
kSpreadBoss
1
ISpread::QueryLayer
4..*
«boss class»
kSpreadLayerBoss
The interface IXMLReferenceData
links objects in the native document
model to the logical structure.
Document objects that are
placeholders for content
such as text, images can be
of type kSplineItemBoss, one
of many page item classes.
1
IHierarchy::GetChildUID
Classes that don't have this interface
can't be associated with elements
in the logical structure.
0..*
«boss class»
kSplineItemBoss
IGraphicFrameData
1 11
IHierarchy::GetChildUID
IHierarchy::GetChildUID
IHierarchy::GetChildUID
0..1
0..1
«boss class»
kPlaceHolderItemBoss
IImageItem
IXMLReferenceData
«boss class»
kImageItem
0..1
«boss class»
kMultiColumnItemBoss
IXMLReferenceData
ITextColumnSizer
GetChildUID
1
1..*
A graphic frame with
unplaced content
has an instance of
this type as its
child
ITextFrame::GetTextModelUID
1
1
«boss class»
kTextStoryBoss
XML Productivity Features
«boss class»
kFrameItemBoss
ITextModel
IXMLReferenceData
There are other types
that can be children
of a graphic frame; see
kDrawablePageItemBoss
subclasses for others
83
XML Productivity Features
Appendix
Backing store
A backing store is a repository that stores part of the logical structure of an InDesign CS
document, along with unplaced content. A backing store manages a collection of boss objects
that each have the interface IIDXMLElement. When you tag a content item in the document,
you create a new instance of a boss object (e.g. kTextXMLElementBoss) in a backing store that
represents an element in the logical structure.
The top-level persistence mechanism for the native document model (“Native document
model, showing content items” on page 82) is what we call UID-based; so, each instance of the
classes shown in the model, such as kSpreadBoss, would have a record number or UID
(Unique Identifier) associated with it in the document’s database.
UID-based objects can also store persistent boss objects that themselves do not have UIDs; this
model is used for attributes, and widely within the Table and XML subsystems. We call this
“container-managed persistence” (CMP) and distinguish it from the conventional UID-based
persistence mechanism. The down-side of CMP in the InDesign CS API is that the container
determines how its own storage is managed and there are slightly different semantics for each
of the containers, e.g. storage of attributes differs from tables, which differs slightly from XML.
The up-side is that the implementation is very efficient compared to UID-based persistence.
A backing store (kSBOSPageBoss) is a storage container for “small boss objects”. The
container (instance of kSBOSPageBoss) has a UID but the objects that it stores do not. The
objects managed by the backing store have keys or “logical IDs”; see
XMLReference::GetLogicalID().
84
XML Productivity Features
Appendix
FIGURE 69
Backing stores
Root node of the
native document
model
1
IStoryList::GetNthTextModelUID (numStories-1)
IStoryList::GetNthUserAccessibleStoryUID
«boss class»
kDocBoss
1
"Small boss object store" or SBOS is
the storage for the objects that
represent the logical structure.
The class kSBOSPageBoss is
opaque to client code and has no
public interfaces of use.
It is included to give a concrete
name to the backing store concept
1
«boss class»
kTextStoryBoss
owns
1
Root backing store
«boss class»
kTextStoryBoss
owns
1
Backing store, user story
1
1
«boss class»
kSBOSPageBoss
1
0..*
1
«boss class»
kSBOSPageBoss
1
1
stores
dtdFor
docElement
1
stores
1..*
0..1
«boss class»
kXMLDocumentBoss
«boss class»
kXMLDTDBoss
0..*
«boss class»
kTextXMLElementBoss
Only the root backing store can
contain an instance of kXMLDocumentBoss.
Also, it is the place that an instance of
kXMLDTDBoss would be stored.
«boss class»
kTextXMLElementBoss
The backing store can also contain elements
that represent comments (kXMLCommentBoss),
processing instructions (kXMLPIBoss), i.e. something
that has an IIDXMLElement interface
The root element is held in the root
backing store. It is the
element that appears as Root in
a new document. It is represented by
an instance of kTextXMLElementBoss
Each document has a root backing store, owned by a non-user accessible story
(kTextStoryBoss). This stores the document-level information, such as any DTD associated
XML Productivity Features
85
XML Productivity Features
Appendix
with the document (kXMLDTDBoss), and contains an instance of kXMLDocumentBoss. At
first sight, it might seem odd that the class kTextStoryBoss (for storing a flow of styled text)
owns the root backing store. However, the class kTextStoryBoss is responsible for managing
many low-level containers for text-based content and the class kSBOSPageBoss is precisely
that.
In addition, each user-accessible story has its own backing store; this backing-store
(kSBOSPageBoss) contains the XML elements that represent any marked-up text ranges in the
story.
The logical structure is distributed across the backing stores for all the stories in a document; as
a consumer of the model, you do not need to be aware of this in your day-to-day activities.
However, if you probe deeper into extending the model, then this may become significant.
A backing store is an example of the use of container-managed persistence; an object of class
kSBOSPageBoss (“Small Boss Object Store”) is responsible for maintaining a collection of boss
objects that each aggregate the interface IIDXMLElement. Each kSBOSPageBoss object is
owned by a boss object of class kTextStoryBoss.
Root backing store and notification
Even though there are multiple backing stores (kSBOSPageBoss objects) in a document, only
one, the root backing store, stores an instance of kXMLDocumentBoss.
The root backing store is owned by a boss object of class kTextStoryBoss that is present in
every document as a non-user accessible story. This object has associations with various lowlevel boss objects, which implement the storage for the elements in the logical structure. The
elements are held in a “small boss object store” (kSBOSPageBoss) owned by this
kTextStoryBoss. The architecture of the backing store is largely opaque to client code and there
are no public APIs of interest on kSBOSPageBoss. However, there are various facades (e.g.
IXMLUtils) and helper classes (e.g. XMLReference) that encapsulate interaction with the
backing store.
When the logical structure of a document changes, the commands that change the logical
structure notify about changes in the backing store. The subject for the change is the story that
owns a particular backing store. Note that the subject for notifications about change in the
logical structure is a UID-based object (instance of kTextStoryBoss).
You can find a snippet of code showing the correct way to acquire of the backing store subject
in the figure entitled “Code acquiring the root backing store subject” on page 86. Consult the
table entitled “Low-level command notification details” on page 87 for the other information
required to listen for changes in document logical structure. At some point, this information
should be present in the API documentation, but currently sits off to one side.
FIGURE 70
Code acquiring the root backing store subject
// The XML document element lives in the root backing store
InterfacePtr<IIDXMLElement> docElement(Utils<IXMLUtils>()->QueryDocElement(db));
UIDRef baseUIDRef = docElement->GetXMLReference().GetUIDRef();
// This refers to an instance of kTextStoryBoss, which is a non user-accessible
// story present in every document that manages the XML information in a doc.
InterfacePtr<ISubject> backingSubject(baseUIDRef, UseDefaultIID());
86
XML Productivity Features
Appendix
//
//
//
//
//
you need the above subject if you want to listen for changes
in the document’s logical structure. For instance, the next line shows
how a command to create a new element in the structure notifies:
backingSubject->Change(kXMLCreateElementCmdBoss,
IID_IIDXMLELEMENT, this);
Low-level command notification
This section provides notification details for low-level commands that are processed by the
XML subsystem to allow you to observe these commands being processed, not to process
them. It is recommended to check the use-cases for the wrapper methods, e.g. on
IXML<whatever>Commands or IXML<whatever>, rather than trying to parameterize and
process the low-level commands directly.
If there are gaps in the wrapper methods, then the use-cases specify how to parameterize and
process the low-level command (for instance, see “Applying a mapping” on page 50).
Command output may be stored in the item-list of a command boss object on output, which is
sent as the changedBy parameter in the IObserver::Update message. When implementing an
observer, you can cast the changedBy parameter of the Update method to an interface pointer
of type ICommand* as shown below.
ICommand* iCommand = (ICommand*)changedBy;
const UIDList itemList = iCommand->GetItemListReference();
When the command output shows that the output is stored in an interface on the command
(e.g. as an XMLReference), then you might write code like this:
InterfacePtr<IXMLReferenceData> cmdData(iCommand, UseDefaultIID());if(cmdData) {
XMLReference xmlRef = cmdData->GetReference();...}
TABLE 1 Low-level command notification details
Boss ClassID (theChange)
Subject
Protocol
Command
output, if any
kImportXMLFileCmdBoss
Document (kDocBoss)
into which content was
imported
IID_IIMPORTMANAG
ER
IImportFileCmdD
ata::GetSysFile()
stores path of file
imported
kXMLCreateTagCmdBoss
Aggregates IXMLTagList,
e.g. kDocWorkspaceBoss
or kWorkspaceBoss
IID_IXMLTAGLIST
Item-list contains
UID of
kXMLTagBoss
created
kXMLSetTagColorCmdBoss
Aggregates IXMLTagList,
e.g. kDocWorkspaceBoss
IID_IXMLTAGLIST
Item-list contains
UID of
kXMLTagBoss
processed
kLoadTagListCmdBoss
Aggregates IXMLTagList,
e.g. kDocWorkspaceBoss
IID_IXMLTAGLIST
Item-list contains
UIDs of
kXMLTagBoss
objects added
XML Productivity Features
87
XML Productivity Features
Appendix
Boss ClassID (theChange)
Subject
Protocol
Command
output, if any
kXMLDeleteTagCmdBoss
Aggregates IXMLTagList,
e.g. kDocWorkspaceBoss
IID_IXMLTAGLIST
Item-list contains
UIDs of objects
that were deleted
kXMLCreateElementCmdBoss
Story (kTextStoryBoss)
that owns root backing
store
IID_IIDXMLELEMENT
IXMLCreateElem
entCmdData to
get XMLReference
kXMLDeleteElementCmdBoss,
kXMLDeleteElementAndConten
tCmdBoss
Story (kTextStoryBoss)
that owns root backing
store
IID_IIDXMLELEMENT
IXMLDeleteEleme
ntCmdData to get
XMLReference
kXMLMoveElementCmdBoss
Story (kTextStoryBoss)
that owns root backing
store
IID_IIDXMLELEMENT
IXMLMoveEleme
ntCmdData to get
XMLReference
kXMLPlaceElementCmdBoss
Story (kTextStoryBoss)
that owns root backing
store
IID_IIDXMLELEMENT
IXMLReferenceD
ata to get
XMLReference
kXMLMapTagToStyleCmdBoss
Target workspace,
aggregates
IXMLTagToStyleMap
IID_IXMLTAGTOSTYL
EMAP
kXMLUnMapTagToStyleCmdB
oss
Target workspace,
aggregates
IXMLTagToStyleMap
IID_IXMLTAGTOSTYL
EMAP
kXMLMapStyleToTagCmdBoss
Target workspace, with
IXMLStyleToTagMap
IID_IXMLSTYLETOTA
GMAP
kXMLUnMapStyleToTagCmdB
oss
Target workspace, with
IXMLStyleToTagMap
IID_IXMLSTYLETOTA
GMAP
kXMLCreatePICmdBoss
Story (kTextStoryBoss)
that owns root backing
store
IID_IIDXMLELEMENT
IXMLCreateElem
entCmdData for
XMLReference
kXMLCreateCommentCmdB
oss
Story (kTextStoryBoss)
that owns root backing
store
IID_IIDXMLELEMENT
IXMLCreateElem
entCmdData for
XMLReference
Entities supported
There are some standard entities supported by default by the XML subsystem, shown in the
table “Standard entities supported” on page 89. If you need to support a wider set, for instance,
the entire ISO-LATIN 1 character entities (e.g. &174; for ™, trademark), then you will find that
it is possible to use them with the applications if they are defined in DTD. For instance,
Simplified DocBook [http://www.oasis-open.org/docbook/xml/simple/sdocbook/] contains
additional entity definitions within its DTD to support ISO-LATIN 1.
88
XML Productivity Features
Appendix
TABLE 2 Standard entities supported
Entity
Meaning
Description
&amp;
&
Ampersand
&lt;
<
Less than
&gt;
>
Greater than
&apos;
'
Apostrophe
&quot;
"
Quote
&#xa;
CR
Character replacement entity for carriage return
&#xd;
LF
Character replacement entity for line feed
Assets from XSLT example
FIGURE 71
Basic grammar for article-based publications
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT publication (article)+>
<!ELEMENT article (article-title, body)>
<!ELEMENT body (title | subhead | para)+>
<!ELEMENT article-title (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT subhead (#PCDATA)>
<!ELEMENT emphasis (#PCDATA)>
<!ENTITY % pub.content "#PCDATA">
<!ELEMENT para (%pub.content; | emphasis)*>
FIGURE 72
Fragment of XSL stylesheet to convert NITF to basic pub
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"></xsl:strip-space>
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates></xsl:apply-templates>
</xsl:template>
<!-- include content from these elements -->
<xsl:template match="nitf|block|body.head|ul">
<xsl:apply-templates></xsl:apply-templates>
</xsl:template>
<!-- exclude content we are not interested in with this empty template -->
<xsl:template match="*"/>
<xsl:template match="body">
<article><xsl:apply-templates></xsl:apply-templates></article>
</xsl:template>
<xsl:template match="body.content">
XML Productivity Features
89
XML Productivity Features
References
<body><xsl:apply-templates></xsl:apply-templates></body>
</xsl:template>
<xsl:template match="p">
<para><xsl:apply-templates></xsl:apply-templates></para>
<xsl:text>
</xsl:text></xsl:template>
<xsl:template match="hedline">
<article-title><xsl:value-of select="hl1"/></article-title><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="hl1">
<title><xsl:value-of select="."/></title><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="nitf-table">
<para><emphasis>Table omitted on import</emphasis></para><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="hl2">
<subhead><xsl:apply-templates></xsl:apply-templates></subhead><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="em">
<emphasis><xsl:apply-templates></xsl:apply-templates></emphasis>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="org">
<xsl:text> </xsl:text>
<emphasis><xsl:apply-templates></xsl:apply-templates></emphasis>
</xsl:template>
<xsl:template match="li">
<para><xsl:apply-templates></xsl:apply-templates></para>
<xsl:text>
</xsl:text></xsl:template>
</xsl:stylesheet>
References
90
•
Adobe PDF Reference [http://partners.adobe.com/asn/tech/pdf/specifications.jsp]
•
Mobile SVG Specification [http://www.w3.org/TR/SVGMobile12/]
•
Walsh N, Muellner L. (1999). DocBook, The Definitive Guide. O’Reilly & Associates,
Inc., CA
•
W3, HTML Table Model. [http://www.w3.org/TR/REC-html40/struct/tables.html]
•
XHTML. [http://www.w3.org/MarkUp/]