How do I select the previous text nodes of a node starting from a specific node and not from the root node?

How do I select the previous text nodes of a node starting from a specific node that I know, instead of getting the text nodes from the root node?

When I call the bottom from the text template match node, I get all the previous text nodes from the root. I want to modify the above code snippet to select only the text nodes that appear after the node that have a specific id like 123. ie something like // * [@id = '123']

          <xsl:template match="text()[. is $text-to-split]"> 
          <xsl:variable name="split-index" as="xsd:integer" 
           select="$index - sum(preceding::text()/string-length(.))"/> 
          <xsl:value-of select="substring(., 1, $split-index - 1)"/> 
          <xsl:copy-of select="$new"/> 
          <xsl:value-of select="substring(., $split-index)"/> 
          </xsl:template> 

         <xsl:variable name="text-to-split" as="text()?" 
         select="descendant::text()[sum((preceding::text(), .)/string-length(.)) ge $index][1]"/> 

      

How do I include a condition where I use the before :: text inorder to select the preceding text nodes relative to a specific node id that I know?

+2


a source to share


2 answers


Here are some options you can use :

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

 <xsl:variable name="vStart" select="/*/*[@myId='123']/text()"/>
 <xsl:variable name="vEnd" select="/*/*[last()]"/>

    <xsl:template match="/">
      <xsl:value-of select=
       "*/*[last()]
             /sum(preceding::text()
                 intersect
                  $vStart/following::text()
                  )
     "/>
---------------
      <xsl:value-of select=
       "*/*[last()]
             /sum(preceding::text()[. >> $vStart])
     "/>
--------------- 
      <xsl:value-of select=
       "sum(/*/*[. >> $vStart and . &lt;&lt; $vEnd])
     "/>
    </xsl:template>
</xsl:stylesheet>

      

When this transformation is applied to the following XML document :



<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num myId='123'>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>010</num>
</nums>

      

the desired results are obtained :

30
---------------
      30
--------------- 
      30

      

+1


a source


In XPath 2.0, you can use the <<

and operators to compare node >>

. For instance:

preceding-sibling::text()[. >> $foo]

      



will select all source text nodes preceding the current one that follow the order of node $foo

. You can of course use an expression instead $foo

- in your case //*[@id='123']

- although binding to a variable and then using that in a filter might be easier to optimize the XSLT processor.

See this for a detailed specification of these operators.

+1


a source







All Articles