[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: inserting a child element while honoring the paren

Subject: Re: inserting a child element while honoring the parent element's content model
From: "Eliot Kimber eliot.kimber@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 20 Feb 2023 16:19:06 -0000
Re:  inserting a child element while honoring the paren
I dont know that its a better solution, but I often use milestone nodes
and the << and >> operators to position things:

<xsl:variable name=fromHere as=element() select=p[1]/>
<xsl:variable name=beforeParaNodes as=node()* select=node()[. <<
$fromHere]/>

I find this especially handy for getting nodes between two variable points,
like all nodes before me that are preceding siblings or descendants of the
first child of my parentthis is a challenge that comes up in DITA with some
frequency because of the rules around ID uniqueness within topics, for which
theres no easy single container.

Cheers,

E.
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> |
Twitter<https://twitter.com/servicenow> |
YouTube<https://www.youtube.com/user/servicenowinc> |
Facebook<https://www.facebook.com/servicenow>

From: Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sunday, February 19, 2023 at 10:37 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject:  inserting a child element while honoring the parent element's
content model
[External Email]

________________________________
Hi everyone,

I needed to insert a child element while honoring the parent element's content
model. The solution took me some time to figure out, so I thought Id share it
here.

Consider a <topic> element with the following content model:

topic = a?, b?, c?, j?, x?, y?, z?, topic*

Given the following input document with no <j> elements:

<?xml version="1.0" encoding="utf-8"?>
<topic>
  <!-- this is a comment -->
  <a/>
  <?my-a-pi?>
  <b/>
  <y/>

  <topic>
    <!-- y -->
    <y/>
  </topic>

  <topic>
    <!-- c -->
    <c/>
  </topic>

</topic>

I want to insert <j> into every <topic> element. To do this, I apply the
following general template that calls an add-j moded template on every
<topic> element lacking a <j>:

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="topic[not(j)]">
    <xsl:variable name="result" as="element()">
      <xsl:apply-templates select="." mode="add-j"/>
    </xsl:variable>
    <xsl:apply-templates select="$result"/>
  </xsl:template>

Then I define the add-j mode as follows:

  <!-- add <j> to <topic>, honoring the following content model:
         topic = a?, b?, c?, j, x?, y?, z?, topic* -->
 <xsl:template match="topic[not(j)]" mode="add-j">
    <xsl:variable name="stuff-before-j"
select="(a|b|c)/(.|preceding-sibling::node())" as="node()*"/>
    <xsl:copy>
      <xsl:sequence select="@*|$stuff-before-j"/>
      <j/>
      <xsl:sequence select="node() except $stuff-before-j"/>
    </xsl:copy>
  </xsl:template>

The tricky part was obtaining $stuff-before-j, since I wanted a
preceding-or-self:: axis to retain any PIs or comments in their correct
place. Once I got that figured out, the rest fell into place.

The reason for a separate add-j moded template is that in my full
stylesheet, I have many templates doing things in many different places, and
so I use moded templates and <xsl:apply-templates/> so that everything plays
well together.

The solution works in either direction (stuff-before or stuff-after). In our
case, we are using DITA and the topics at the end of the content model can be
other specialized elements, so using the stuff-before flavor lets me match
any specialized topic that might follow.

I have much uglier implementations of content-model-aware insertion in past
stylesheets that Ill need to convert to this form.


  *   Chris

-----
Chris Papademetrious
Tech Writer, Implementation Group
(610) 628-9718 home office
(570) 460-6078 cell

XSL-List info and archive<http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe<http://lists.mulberrytech.com/unsub/xsl-list/3453418> (by
email<>)

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.