xsl-list
[Top] [All Lists]

Re: [xsl] Add id to next element

2022-05-19 22:12:54
Thank you for the many suggestions!  I like the solution that process
<target> in a mode.  I will adapt it to the actual XML that I am
processing..

Regards,
Raghavendra.

On Thu, May 19, 2022 at 11:24 PM Eliot Kimber
eliot(_dot_)kimber(_at_)servicenow(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>
wrote:

The typical way to do it is to have the processing of the section element get 
the value from the preceding target element:



  <xsl:template match="section">
    <xsl:variable name="id" as="xs:string?"
      select="preceding-sibling::target[1]/@refid"
    />
    <xsl:copy>
        <xsl:attribute name="id"
          select="if ($id) then $id else generate-id(.)"
        />
        <xsl:apply-templates mode="#current"/>
    </xsl:copy>
  </xsl:template>



This assumes that every <section> is preceded by a <target> element. If 
that’s not the case then you’d have to do a little more work to only select a 
target that follows any preceding sections:



    <xsl:variable name="precedingSection" as="element()?" 
select="preceding-sibling::section[1]"/>
    <xsl:variable name="id" as="xs:string?"
      select="(preceding-sibling::target[. &gt;&gt; 
$precedingSection])[last()]/@refid"
    />



Or something close to that—this is (or intends to be) selecting the nearest 
<target> that follows the nearest preceding <section>, which should be the 
<target> that applies to the current <section>.



For the <target> element you have a template that does nothing.



Instead of constructing the $id variable as I am here, you could instead do 
apply-templates to the preceding <target> in a distinct mode and have it 
generate the attribute—that’s probably cleaner but a little more work to set 
up, but it’s an easy refactor to apply to my original code:



  <xsl:template match="section">
    <xsl:copy>
        <xsl:attribute name="id" select="generate-id(.)"/>
        <xsl:apply-templates mode="set-section-id"
          select="(preceding-sibling::target[. &gt;&gt; 
$precedingSection])[last()]"
        />

        <xsl:apply-templates mode="#current"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="target" mode="set-section-id">
      <xsl:attribute name="id"
        select="@refid"
      />
  </xsl:template>



Note that the first xsl:attribute name=”id” will be overridden by one 
generated by the target element if there is one (by the “last attribute 
declaration wins” rule for element construction).



Alternatively you could have the processing for the <target> element call 
templates on its following <section> and pass the refid value as a parameter. 
But that would not be typical XSLT practice and would make it hard to find 
the processing for <section>, which is obviously the primary component being 
processed.



There are other ways to do it, of course, but I think this approach would be 
normal best practice.



Cheers,



E.

_____________________________________________

Eliot Kimber

Sr Staff Content Engineer

O: 512 554 9368

M: 512 554 9368

servicenow.com

LinkedIn | Twitter | YouTube | Facebook



From: Raghavendra Nyshadham nyraghu27132(_at_)gmail(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>
Date: Thursday, May 19, 2022 at 12:18 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com 
<xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Subject: [xsl] Add id to next element

[External Email]


I am trying to write an XSLT stylesheet to transform an XML document
(that was generated by Python Docutils) to HTML5. Here is a fragment
from the source document:

<target refid="foo"/>
<section>

The <target> element specifies an identifier for the next element,
i.e., <section>. So I want something like

<section id="foo">

in the HTML output. I am unable to figure out an XSLT way to attach an
attribute to the next element while processing <target>. Would
appreciate any help.

Thanks and regards,
Raghavendra.

XSL-List info and archive
EasyUnsubscribe (by email)
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--


<Prev in Thread] Current Thread [Next in Thread>