开发者

How to count all <w:p>nodes based on my specfic criteria using xslt 2.0?

This is my XML file.

<w:document xmlns:w="w">

    <w:body>                    
        <w:p>
          <w:r>
             <w:pict>
                 <v:shape xmlns:v="v">                   
                     <v:textbox>   
                 <w:txbxContent>    
                     <w:p>             <!-- My Ignore case -->
                <w:r>
                       <w:t>paragraph1
                                </w:t>
                               </w:r>
                            </w:p>  
               </w:txbxContent>
                        </v:textbox>
                      </v:shape>
                   </w:pict>
                </w:r>   
                <w:r>
                  <w:t>Normal Paragraph1</w:t>
                </w:r>

              </w:p>

             <w:p>
                <w:r>
                  开发者_运维知识库 <w:t>paragraph2
                   </w:t>
                </w:r>
             </w:p>  
             <w:p>
                <w:r>
                   <w:t>paragraph3
                   </w:t>
                </w:r>
             </w:p>  

             <w:p>
                <w:r>
                   <w:t>paragraph4
                   </w:t>
                </w:r>
             </w:p>  
             <w:p>
                <w:r>
                   <w:t>paragraph5
                   </w:t>
                </w:r>
             </w:p>  
           <w:tbl>
              <w:tr>
                 <w:tc>
                     <w:p><w:r><w:t>para6</w:t></w:r></w:p>
                 </w:tc>
                 <w:tc>
                   <w:p><w:r><w:t>para7</w:t></w:r></w:p><!-- Assume This is my Current Node -->
                </w:tc>   
                <w:tc>
                     <w:p><w:r><w:t>para8</w:t></w:r></w:p>
                </w:tc>
              </w:tr>
            </w:tbl>        
   </w:body>

</w:document>

Logic:1

So, now I want to count all preceding <w:p> nodes only within <w:body> tag. For example, now we have 5 nodes from <w:body>.

Logic:2

then if (<w:tbl> inside <w:body>) then count all <w:p> inside the <w:tbl> until the current node will reach.

So, the expected final is :7.

I have written query for this, but it is counting wrongly.

<xsl:value-of select="count($currentNode/preceding::w:p)"/>

It is written 8 because it will also count <w:p> inside <w:p>(see, my ignore case on my code). I don't want it.

I need the total count like logic1+logic2.


It sounds like you want to ignore w:p elements that are nested within other w:p elements.

If so, then you need to modify for statement to only include w:p element which have no w:p element as an ancestor.

<xsl:value-of select="count($currentNode/preceding::w:p[not(ancestor::w:p)])"/>

This should return a value of 7, instead of 8. I am assuming the current node is para8 here, by the way.

So, assuming the following XML document

<w:document xmlns:w="w">
   <w:body>
      <w:p>
         <w:r>
            <w:pict>
               <v:shape xmlns:v="v">
                  <v:textbox>
                     <w:txbxContent>
                        <w:p><!-- My Ignore case -->
                           <w:r>
                              <w:t>paragraph1 </w:t>
                           </w:r>
                        </w:p>
                     </w:txbxContent>
                  </v:textbox>
               </v:shape>
            </w:pict>
         </w:r>
         <w:r>
            <w:t>Normal Paragraph1</w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:r>
            <w:t>paragraph2 </w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:r>
            <w:t>paragraph3 </w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:r>
            <w:t>paragraph4 </w:t>
         </w:r>
      </w:p>
      <w:p>
         <w:r>
            <w:t>paragraph5 </w:t>
         </w:r>
      </w:p>
      <w:tbl>
         <w:tr>
            <w:tc>
               <w:p>
                  <w:r>
                     <w:t>para6</w:t>
                  </w:r>
               </w:p>
            </w:tc>
            <w:tc>
               <w:p>
                  <w:r>
                     <w:t>para7</w:t>
                  </w:r>
               </w:p>
            </w:tc>
            <!-- Assume This is my Current Node -->
            <w:tc>
               <w:p>
                  <w:r>
                     <w:t>para8</w:t>
                  </w:r>
               </w:p>
            </w:tc>
         </w:tr>
      </w:tbl>
   </w:body>
</w:document>

If you use the following XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="w">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="/">
      <xsl:variable name="currentNode" select="//w:p[w:r/w:t = 'para8']" />
      Old: <xsl:value-of select="count($currentNode/preceding::w:p)"/> 
      -----
      New: <xsl:value-of select="count($currentNode/preceding::w:p[not(ancestor::w:p)])"/> 
   </xsl:template>

</xsl:stylesheet>

Then the following is returned:

  Old: 8 
  -----
  New: 7
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜