Re: [xsl] Selecting everything "before" and "after" a specific node

Subject: Re: [xsl] Selecting everything "before" and "after" a specific node
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Thu, 02 Apr 2009 13:51:37 +0200
Paul Harvey wrote:
Hi,
Ibve searched and posted on another list, but have not found an answer to this problemb&
I have XML like this...

<A i=b1b>
      <B i=b2b>
            <C i=b3b/>
      </B>
      <B i=b4b>
            <C i=b5b>
                  <D i=b6b/>
                  <D i=b7b>
                        <E i=b8b/>
                        <E i=b9b msg="get me out of here!"/>
                        <E i=b10b/>
                  </D>
                  <D i=b11b/>
            </C>
            <C i=b12b/>
      </B>
</A>
And I need to break it out into 3 nodesets, delimited by the <E i=b9b msg="get me out of here!"/> such that Ibd end up with...
<ROOT>
       <BEFORE>
        <A i=b1b>
                  <B i=b2b>
                        <C i=b3b/>
                  </B>
                  <B i=b4b>
                        <C i=b5b>
                              <D i=b6b/>
                              <D i=b7b>
                                    <E i=b8b/>
                              </D>
                        </C>>
                  </B>
        </A>
       </BEFORE>
       <PULLED_OUT>
            <E id=b9b msg="get me out of here!"/>
       </PULLED_OUT>
       <AFTER>
        <A i=b1b>
                  <B i=b4b>
                        <C i=b5b>
                              <D i=b7b>
                                    <E i=b10b/>
                              </D>
                              <D i=b11b/>
                        </C>
                        <C i=b12b/>
                  </B>
        </A>
       </AFTER>
</ROOT>

Any suggestions as to how Ibd go about that?

Here is an attempt with XSLT 2.0:


<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="2.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

<xsl:variable name="pn" select="//*[@i = '9']"/>

  <xsl:template match="/">
    <ROOT>
      <BEFORE>
        <xsl:apply-templates select="*" mode="before"/>
      </BEFORE>
      <PULLED_OUT>
        <xsl:copy-of select="$pn"/>
      </PULLED_OUT>
      <AFTER>
        <xsl:apply-templates select="*" mode="after"/>
      </AFTER>
    </ROOT>
  </xsl:template>

<xsl:template match="*[. &gt;&gt; $pn or . is $pn]" mode="before"/>

<xsl:template match="*[. is $pn or empty(. intersect $pn/ancestor::*) and empty(. intersect $pn/following-sibling::*)]" mode="after"/>

  <xsl:template match="*" mode="before">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="before"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*" mode="after">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="after"/>
    </xsl:copy>
  </xsl:template>

<xsl:template match="@* | text() | comment() | processing-instruction()" mode="after before">
<xsl:copy/>
</xsl:template>


</xsl:stylesheet>


--


	Martin Honnen
	http://JavaScript.FAQTs.com/

Current Thread