选择包含混合内容的节点或仅包含XPath的文本

时间:2012-07-05 08:27:45

标签: xslt-1.0 xpath-1.0

使用XPath 1.0和XSLT 1.0我需要选择混合内容或文本的直接父项。请考虑以下示例:

<table class="dont-match">
    <tr class="dont-match">
        <td class="match">Mixed <strong class="maybe-match">content</strong> in here.</td>
        <td class="match">Plain text in here.</td>
        <td class="dont-match"><img src="..." /></td>
    </tr>
</table>
<div class="dont-match">
    <div class="dont-match"><img src="..." /></div>
    <div class="match">Mixed <em class="maybe-match">content</em> in here.</div>
    <p class="match">Plain text in here.</p>
</div>

显然,课程matchmaybe-matchdont-match仅用于演示目的,不可用于匹配。 maybe-match意味着最好不要匹配,但我可以自己解决问题,以防难以排除这些问题。

非常感谢提前!

2 个答案:

答案 0 :(得分:2)

要获得匹配和可能匹配,您可以使用

 //*[count(text())>=1]

如果你的xml解析器只忽略空白文本节点,或者

//*[normalize-space(string(./text())) != ""]

可能通过检查一些管弦乐队是否匹配来过滤掉可能的匹配,但随后它变得丑陋(仅作为文本节点的空格):

//*[(normalize-space(string(./text())) != "") and count(./ancestor::*[normalize-space(string(./text())) != ""]) = 0]

答案 1 :(得分:2)

对于“匹配”使用

//*[text()[normalize-space()] and not(../text()[normalize-space()])]

对于“可能匹配”,请使用

//*[../text()[normalize-space()]]

基于XSLT的验证

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:copy-of select=
      "//*[text()[normalize-space()] and not(../text()[normalize-space()])]"/>
==========
   <xsl:copy-of select="//*[../text()[normalize-space()]]"/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML (包装到单个顶部元素中以成为格式良好的XML文档):

<t>
<table class="dont-match">
    <tr class="dont-match">
        <td class="match">Mixed <strong class="maybe-match">content</strong> in here.</td>
        <td class="match">Plain text in here.</td>
        <td class="dont-match"><img src="..." /></td>
    </tr>
</table>
<div class="dont-match">
    <div class="dont-match"><img src="..." /></div>
    <div class="match">Mixed <em class="maybe-match">content</em> in here.</div>
    <p class="match">Plain text in here.</p>
</div>
</t>

评估两个XPath表达式中的每一个,并将选定的节点复制到输出中:

<td class="match">Mixed <strong class="maybe-match">content</strong> in here.</td>
<td class="match">Plain text in here.</td>
<div class="match">Mixed <em class="maybe-match">content</em> in here.</div>
<p class="match">Plain text in here.</p>
==========
   <strong class="maybe-match">content</strong>
<em class="maybe-match">content</em>

正如我们所看到的,两个表达式都选择完全想要的元素。