Re: [xsl] inserting a child element while honoring the parent element's content model

Subject: Re: [xsl] inserting a child element while honoring the parent element's content model
From: "Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 23 Feb 2023 10:31:00 -0000
Hi Vincent, Wendell, Michael,

Hey, that is pretty slick! I had noticed the similarity of the compact
RelaxNG<https://www.oasis-open.org/committees/relax-ng/compact-20021121.html>
format to regex, but it didnbt click with me that the regex engine itself
could be pressed into service for content model validation. Very cool.

(Side note: if you work with RelaxNG and youbre not aware of the
jing/trang<https://github.com/relaxng/jing-trang> command-line tools for
RelaxNG schema checking/conversion, I suggest you check them out. I use them
for two DITA-related scripts I wrote,
content_model.pl<https://github.com/chrispy-snps/DITA-plugin-utilities#conten
t_modelpl> and
ditaot_validate.pl<https://github.com/chrispy-snps/DITA-ditaot-utilities#usin
g-ditaot_validatepl>.)

My situation is a bit different from static content model validation. Ibm
inserting new content into existing content, which means that the
content-model-awareness must also be implemented in XSLT. For my immediate
needs, I think a simple ordered-list model for content insertion is
sufficient. Given the following content models:

topic = element topic { title, titlealts?, (shortdesc | abstract)?, prolog?,
body?, related-links?, topic* }
prolog = element prolog { author*, source?, publisher?, copyright*,
critdates?, permissions?, (metadata | change-historylist)*, resourceid*, (data
| sort-as | data-about | foreign | mathml | svg-container | unknown)* }
metadata = element metadata { audience*, category*, keywords*, prodinfo*,
othermeta*, (data | sort-as | data-about | foreign | mathml | svg-container |
unknown)* }

I could derive simple ordered lists, stored in a map:

<xsl:variable name="content-models" as="map(xs:string, xs:string*)"
select="map {
  'topic': ('title', 'titlealts', 'shortdesc', 'abstract', 'prolog', 'body',
'related-links', 'topic'),
  'prolog': ('author', 'source', 'publisher', 'copyright', 'critdates',
'permissions', 'metadata', 'change-historylist', 'resourceid', 'data',
'sort-as', 'data-about', 'foreign', 'mathml', 'svg-container', 'unknown'),
  'metadata': ('audience', 'category', 'keywords', 'prodinfo', 'othermeta',
'data', 'sort-as', 'data-about', 'foreign', 'mathml', 'svg-container',
'unknown')
}"/>

Then, given (1) an existing element, (2) a path into that element, and (3) a
sequence containing content to insert at that path:

<xsl:variable name="existing-element" select="/topic" as="element()"/>
<xsl:variable name="new-path" select="'prolog/metadata/keywords'"
as="xs:string"/>
<xsl:variable name="new-content" as="element()*">
  <keyword>term 1</keyword>
  <keyword>term 2</keyword>
</xsl:variable>

I could call some moded template to perform the insertion, reusing existing
elements or creating new elements as the path is traversed:

<xsl:variable name="updated-element" as="element()"/>
  <xsl:apply-templates select="$existing-element" mode="insert-stuff">
    <xsl:with-param name="existing-element" select="$existing-element"
as="element()"/>
    <xsl:with-param name="new-path" select="$new-path" as="xs:string"/>
    <xsl:with-param name="new-content" select="$new-content" as="element()*"
tunnel="yes"/>
  </xsl:apply-templates>
</xsl:variable>

The moded template can probably call itself recursively. I just need to fiddle
with it to get the ordered-list insertion part figured out.

I guess if I wanted to get fancy, I could use the regex-based validation
approach to iterate to find the first valid insertion position at each level
of hierarchy! I will add that to my list of rainy-day projectsb&


  *   Chris


From: Lizzi, Vincent vincent.lizzi@xxxxxxxxxxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Wednesday, February 22, 2023 4:03 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [xsl] inserting a child element while honoring the parent
element's content model

Hi Chris,

The idea was from Rick Jelliffe, although I donbt have the exact citation
now. Here is a small example:

b&omittedb&

_____________________________________________
Vincent M. Lizzi
Head of Information Standards | Taylor & Francis Group
vincent.lizzi@xxxxxxxxxxxxxxxxxxxx<mailto:vincent.lizzi@xxxxxxxxxxxxxxxxxxxx>

Current Thread