xsl-list
[Top] [All Lists]

Re: Performance Question: Expensive Functions in Predicates

2004-05-28 07:58:17
G. Ken Holman wrote:


I have an external entity with each identified applicability using ID:

<appls>
  <appl id="this" appl="yes"/>
  <appl id="that" appl="no"/>
  <appl id="other" appl="yes"/>
</appls>

that I pull into my instance.

I'm presuming that you have different entities for different sets of conditions so that, for example, when you're processing for one target some things are "yes" and when you're processing for a different target those same things may be "no". If so, that implies that you have to change the actual file the external entity resolves to based on the presentation target. How do you do that?

For me this approach would not generalize well because the applicability of a given element may be determined by the processing-time value of a potentially unbounded set of conditions, including things like target language, target country, operating platform, page layout (for print-specific renditions), rendition type (HTML, PDF, Web PDF, etc.), marketing region, product family (for content re-used across products or product families within a large corporation).

Another issue is that in my use cases the author knows what individual condition values a given element applies to (this is for print and Mac OS X help) but not whether or not a given element will be applicable *when processed* because in fact the set of possible conditions cannot be known at authoring time and because the business rules for determining applicability might change even though the document content has not changed.

Therefore applicability must be determined dynamically at processing time in my case.

However, having said all that, there is still a place for this type of indirect applicability specification, namely, defining sets of applicability values that can then be used by reference. This eliminates the problem of having an ever-increasing and constantly-changing set of applicability attributes on elements.

For example, given your markup above, I might refine it to something like:

 <appls>
   <appl id="option-set-01">
     <lang>en-CA</lang>
     <presentationTarget>print</prenentationTarget>
     <platform>Mac</platform>
   </appl>
   <appl id="option-set-02">
     <lang>en-UK</lang>
     <presentationTarget>print</prenentationTarget>
     <platform>Windows</platform>
   </appl>
 </appls>

An authoring system can present either a list of option sets or the author can simply select the options and values and then the system either finds an existing set that matches or synthesizes one if it doesn't exist.

The instance could still use a link to associate elements to their applicability values:

<thing1 appl_doc="my_applicability_sets.xml"
        appl_xpointer="xpointer(//appl[(_at_)id = 'option-set-01'])">...

<thing2 appl_doc="my_applicability_sets.xml"
        appl_xpointer="xpointer(//appl[(_at_)id = 'option-set-02'])">...

But the actual applicability would still be determined dynamically at run time. For example, my is_applicable() utility function might look something like this:

<func:function name="util:is_applicable">
  <xsl:param name="current_node" select="."/>
  <xsl:variable name="condition_set"
       select="util:resolve_xpointer(@appl_doc, @appl_xpointer)"/>
  <func:result
       select="myjavaext:calc_applicability($condition_set[1])"/>
</func:function>

Three points about this approach:

1. I've used the XInclude pattern of having separate attributes for the URI of the target document and the XPointer of the target element(s). I think this is the best design pattern for doing addressing in an XML/URI context for the reasons stated in the XInclude spec.

2. I've put the applicability set into an external document since it's not part of the core document content (many documents could share the same option sets since the set of possible combinations is finite and, in practice will be relatively small, probably on a fraction of the total possible combinations) and is presumably managed by the authoring support system (which in Ken's case is Ken but in my case would be sophisticated software components developed at great expense :-). This is also a reflection of my "external entities are bad pretend they don't exist" policy :-)

3. It uses a procedural language (e.g., Java) to do the actual applicability calculation. This is because I've found it much easier to evaluate complex conditions in Java than XSLT, especially for people who didn't grow up writing Scheme programs. For example, I found writing an XSLT function to correctly evaluate a statment like "print webpdf not_help" almost impossible for my feeble brain but nearly trivial in Java. But maybe it's just me. Certainly the Java implementation is much much simpler at the code level (it doesn't require recursion, for one thing). In addition, I may need the same applicability calculation business logic in other processing contexts, such as within an authoring tool or for content management import, export, or reporting, so it makes sense to implement it generically.

Cheers,

Eliot
--
W. Eliot Kimber
Professional Services
Innodata Isogen
9030 Research Blvd, #410
Austin, TX 78758
(512) 372-8122

eliot(_at_)innodata-isogen(_dot_)com
www.innodata-isogen.com