如何使用 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
所以,现在我想仅在 <w:body>
标记内计算所有前面的 <w:p>
节点。例如,现在我们有来自<w:body>
的 5 个节点。
逻辑:2
然后如果(<w:tbl>
inside <w:body>
)然后计算<w:tbl>
内的所有<w:p>
,直到当前节点到达。
所以,预期的最终结果是:7。
我已经为此编写了查询,但计数错误。
<xsl:value-of select="count($currentNode/preceding::w:p)"/>
之所以写成 8,是因为它也会在 <w:p>
内计算 <w:p>
(请参阅我的代码中的忽略大小写)。我不想要。
我需要像 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 文件