[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
Hi everyone, Here is a template to perform content-model-aware element insertion (more to come): <!-- perform content-aware insertion on an element --> <xsl:template match="*" mode="insert-stuff"> <xsl:param name="path" as="xs:string*"/> <xsl:param name="content" as="element()*" tunnel="yes"/> <!-- if path levels remain to recurse, get the next path level --> <xsl:variable name="path-element-name" select="head($path)" as="xs:string?"/> <xsl:variable name="path-element-original" select="*[name() eq $path-element-name]" as="element()?"/> <!-- choose what to insert in this current element (the "parent") --> <xsl:variable name="parent-name" select="name()" as="xs:string"/> <xsl:variable name="insert-in-parent" as="node()*"> <xsl:choose> <xsl:when test="$path-element-name"> <!-- we are still recursing the path - create or modify the next path element --> <xsl:variable name="path-element-to-process" as="element()"> <xsl:choose> <xsl:when test="$path-element-original"> <!-- the path element exists at this level; use it --> <xsl:sequence select="$path-element-original"/> </xsl:when> <xsl:otherwise> <!-- the path element does not exist at this level; create it --> <xsl:element name="{$path-element-name}"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- recursively process this path element, then insert it into its parent below --> <xsl:apply-templates select="$path-element-to-process" mode="#current"> <xsl:with-param name="path" select="tail($path)" as="xs:string*"/> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <!-- we've reached the end of the path - insert the content at this level --> <xsl:sequence select="$content"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- get the content model we must respect in this current element (the "parent") --> <xsl:if test="empty($content-models($parent-name))"> <xsl:message terminate="yes" expand-text="yes">No content model found for '{$parent-name}'.</xsl:message> </xsl:if> <xsl:variable name="content-model" select="$content-models($parent-name)" as="xs:string+"/> <!--iteratively insert one element at a time into the parent --> <xsl:iterate select="$insert-in-parent"> <xsl:param name="current-parent" select="." as="element()"/> <xsl:on-completion select="$current-parent"/> <xsl:variable name="this-element-to-insert" select="." as="element()"/> <!-- compute an updated parent element with this content element inserted --> <xsl:variable name="new-parent" as="element()"> <!-- get all content up to (and including) the current insertion element type, per the content model --> <xsl:variable name="this-element-name" select="name($this-element-to-insert)" as="xs:string"/> <xsl:if test="empty(index-of($content-model, $this-element-name))"> <xsl:message terminate="yes" expand-text="yes">'{$this-element-name}' not found in content model for '{$parent-name}'.</xsl:message> </xsl:if> <xsl:variable name="preceding-elements" select="$current-parent/*[name() = $content-model[position() <= index-of($content-model, $this-element-name)]]" as="element()*"/> <xsl:variable name="preceding-nodes" select="$preceding-elements/(.|preceding-sibling::node())" as="node()*"/> <!-- create the updated parent element --> <xsl:copy select="$current-parent"> <!-- include the preceding content (if we updated an existing path element, don't include the original) --> <xsl:sequence select="@*, $preceding-nodes except $path-element-original"/> <!-- insert this element --> <xsl:sequence select="$this-element-to-insert"/> <!-- include the following content --> <xsl:sequence select="node() except ($preceding-nodes)"/> </xsl:copy> </xsl:variable> <xsl:next-iteration> <xsl:with-param name="current-parent" select="$new-parent"/> </xsl:next-iteration> </xsl:iterate> </xsl:template>
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|