This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Inserting Elements with XSL


Hello all,
i have a DTD with a few elements of the form
<!ELEMENT elem (a,b?,c?,d?,e?,...)>
which has changed to
<!ELEMENT elem (a,b?,c?,d?,e?,f?,...)>

I'll have to update some hundred files by inserting the
f-Elements into the appropriate place. So far i came up
with the following stylesheet, which appears to work:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="a[not(following-sibling::b|following-sibling::c|
    following-sibling::d|following-sibling::e|following-sibling::f)]">
    <xsl:call-template name="insert"/>
  </xsl:template>
  <xsl:template match="b[not(following-sibling::c|
    following-sibling::d|following-sibling::e|following-sibling::f)]">
    <xsl:call-template name="insert"/>
  </xsl:template>
  <xsl:template match="c[not(following-sibling::d|following-sibling::e|
    following-sibling::f)]">
    <xsl:call-template name="insert"/>
  </xsl:template>
  <xsl:template match="d[not(following-sibling::e|following-sibling::f)]">
    <xsl:call-template name="insert"/>
  </xsl:template>
  <xsl:template match="e[not(following-sibling::f)]">
    <xsl:call-template name="insert"/>
  </xsl:template>
  <xsl:template name="insert">
    <xsl:copy-of select="."/>
    <f/>
  </xsl:template>
</xsl:stylesheet>

Is there something more elegant (read: shorter) to achieve the desired result?
Actually i have some more optional elements before the element to be inserted
and some of the stuff which has to be inserted will be passed as parameters, but
i didn't want to bloat the example even more. (The f-element is there because
there may already be updated files in the pool)

I tried

  <xsl:template match="(a|b|c|d|e)[not(following-sibling::b|following-sibling::c|
    following-sibling::d|following-sibling::e|following-sibling::f)]">
    <xsl:copy-of select="."/>
    <f/>
  </xsl:template>

but this is apparently not a valid match pattern (saxon 6.3 complains).
And it's not really more comprehensible.

Using
  <xsl:template match="*[(name()='a' or name()='b' or ...)
                         and not(following-sibling::*[name()='b' or ...])]">
    <xsl:copy-of select="."/>
    <f/>
  </xsl:template>

isn't all that much more attractive either.

What are the opinions of the gurus?

Regards
J.Pietschmann
-- 

----------------------------------------------------------------------
Zuercher Kantonalbank ZKB        Internet : joerg.pietschmann@zkb.ch
Neue Hard 9                      Telefon  : ++41 01-275 85 03 
Postfach                         Fax      : ++41 01-275 80 34
CH-8010 Zuerich
----------------------------------------------------------------------

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]