views:

224

answers:

1

I want to get the generate-id(.) of all the text nodes after node <m/> and before node </n>. I am looking for some generic XSL and not tightly coupled to the sample input pattern mentioned below. For any input pattern i want to get the ids of all the text nodes between node <m/> and <n/>.

Sample input for better understanding:

<a>
  <b> 
    <c>
      This is first text node
    </c> 
  </b> 
  <d> 
    <e>
      This is my second text node
    </e> 
    <f> 
      This is my <m/>third text node 
    </f> 
    <g>
      One more text node
    </g>
  <h>
    <i>
      This is my fourth text node
    </i>
  </h>
  <j> 
    This is my fifth <n/>text node 
  </j>
  <k> 
    <l>
      This is my sixth text node 
    </l>
  </k>     
</d> 
</a> 

Expected output: Generate id of the text nodes with values "third text node ", "One more text node", "This is my fourth text node", "This is my fifth" which lie inbetween nodes <m/> and <n/>

Please give your ideas.

+3  A: 

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vtextPostM" select="//text()[preceding::m]"/>
 <xsl:variable name="vtextPreN" select="//text()[following::n]"/>

 <xsl:variable name="vtextBN-MandN" select=
  "$vtextPostM[count(.|$vtextPreN) = count($vtextPreN)]"/>

 <xsl:variable name="vNL" select="'&#xA;'"/>
 <xsl:variable name="vQ">"</xsl:variable>

 <xsl:template match="/">
   <xsl:for-each select="$vtextBN-MandN">
    <xsl:value-of select=
     "concat($vNL, 'Id: ', $vQ, generate-id(), $vQ,
            'Text: ', $vQ, ., $vQ)
     "/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document, produces the correct and wanted result:

Id: "IDAOZDLB"Text: "third text node
    "
Id: "IDAQZDLBIDAQZDLB"Text: "
      One more text node
    "
Id: "IDAUZDLBIDAUZDLB"Text: "
      This is my fourth text node
    "
Id: "IDAYZDLB"Text: "
    This is my fifth "

Do note the use of the Kaysian method of nodeset intersection:

$ns1[count(.|$ns2)=count($ns2)]

selects all nodes that belong both to the nodeset $ns1 and to the nodeset $ns2.

Dimitre Novatchev
Thanks it works perfectly.