如何使用 xslt 2.0 根据我的特定标准计算所有 <w:p> 节点?

Posted

技术标签:

【中文标题】如何使用 xslt 2.0 根据我的特定标准计算所有 <w:p> 节点?【英文标题】:How to count all <w:p>nodes based on my specfic criteria using xslt 2.0? 【发布时间】:2011-11-25 20:49:35 【问题描述】:

这是我的 XML 文件。

<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>

逻辑:1

所以,现在我想仅在 &lt;w:body&gt; 标记内计算所有前面的 &lt;w:p&gt; 节点。例如,现在我们有来自&lt;w:body&gt; 的 5 个节点。

逻辑:2

然后如果(&lt;w:tbl&gt; inside &lt;w:body&gt;)然后计算&lt;w:tbl&gt; 内的所有&lt;w:p&gt;,直到当前节点到达。

所以,预期的最终结果是:7。

我已经为此编写了查询,但计数错误。

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

之所以写成 8,是因为它也会在 &lt;w:p&gt; 内计算 &lt;w:p&gt;(请参阅我的代码中的忽略大小写)。我不想要。

我需要像 logic1+logic2 这样的总数。

【问题讨论】:

你错过了说哪个是当前完成计数的节点??? @DimitreNovaatchev::我在上面的代码中提到过。请参阅第 7 段

标签

@_Saravanan:您给我们的文本甚至不是格式良好的 XML 文档:未定义的命名空间 + 未闭合的标签——请更正,否则您的问题根本没有定义。 @_Saravanan:您可能想知道有一个更简单且不会误导的 XPath 表达式来计算所需的计数。 @_Saravanan:你为什么继续提供误导性信息?它是包含“para8”的w:p——而不是根据您的最后评论包含“para7”的那个。请注意提高你的问题的准确性——这个问题仍然完全令人困惑。不仅如此,您的 XML 仍然不是格式正确的——由于没有定义命名空间。 【参考方案1】:

听起来您想忽略嵌套在其他 w:p 元素中的 w:p 元素。

如果是这样,那么您需要修改 for 语句以仅包含没有 w:p 元素作为祖先的 w:p 元素。

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

这应该返回值 7,而不是 8。顺便说一下,我假设当前节点是 para8

所以,假设下面的 XML 文档

<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>

如果您使用以下 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>

然后返回以下内容:

  Old: 8 
  -----
  New: 7

【讨论】:

:非常感谢。请让我试试吧……我很快就会来 @@Tim::Great work tim...非常感谢...它工作得非常好...感谢您的宝贵时间... @@Tim::能否请您参考任何有关 XSLT 编程的好书?我对学习 xslt 非常感兴趣。请帮我参考任何书籍 @Saravanan:请参阅有关优秀 XSLT 书籍/资源的回复:***.com/questions/339930/… @Tim C:这个表达式等价于:count($currentNode/preceding::w:p),因为preceding::ancestor:: 轴不重叠!请修改并更正您的答案。此外,如果您还提供您正在评估此 XPath 表达式所依据的 XML 文档,那就太好了——该问题没有提供格式良好的 XML 文档,并且两个人可能会基于此构造两个不同的格式良好的 XML 文档.

以上是关于如何使用 xslt 2.0 根据我的特定标准计算所有 <w:p> 节点?的主要内容,如果未能解决你的问题,请参考以下文章

SSIS - XML 任务未使用我创建的 XSLT-2.0 转换我的 XML 文件

需要我的XSLT仅从XML输出特定作者(如果可用)

根据 XSLT 中的特定节点值获取节点

XSLT 2.0:根据 for-each -group 的当前索引评估和修改元素值

XSLT 2.0 如何更改数字的默认格式?

支持 XPath 2.0 的 Java XSLT 处理器