2012-07-11 26 views
4

我想使用XPath,發現至少有一個孩子<pre>元素,沒有其他類型的子元素,並且可以選擇文本節點的孩子每天<blockquote>元素的元素:查找只有一個其他類型的孩子

<body><div><!-- arbitrary nesting --> 
    <blockquote><pre>YES</pre></blockquote> 
    <blockquote><p>NO</p></blockquote> 
    <blockquote><pre>NO</pre><p>NO</p></blockquote> 
    <blockquote><p>NO</p><pre>NO</pre></blockquote> 
    <blockquote><pre>YES</pre> <pre>YES</pre></blockquote> 
    <blockquote>NO</blockquote> 
</div></body> 

這個XPath似乎工作,但我懷疑這是過於複雜:

//blockquote[pre][not(*[not(name()="pre")])] 

有沒有更好的(更少的代碼,更高效,更DRY)的方式來選擇我想要什麼?

+0

我認爲有:) – 2012-07-12 12:50:50

回答

2

使用

//blockquote[* and not(*[not(self::pre)])] 

這將選擇至少有一個子元素,並沒有任何元素的孩子,是不是pre元素的XML文檔中的所有元素。

這只是應用double negation law :)。

待辦事項,這個表達是不是一個計算所有元素孩子(因爲選擇權在非pre孩子被發現的那一刻停止)更有效。

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="//blockquote[* and not(*[not(self::pre)])]"/> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被應用所提供的XML文檔:

<body><div><!-- arbitrary nesting --> 
     <blockquote><pre>YES</pre></blockquote> 
     <blockquote><p>NO</p></blockquote> 
     <blockquote><pre>NO</pre><p>NO</p></blockquote> 
     <blockquote><p>NO</p><pre>NO</pre></blockquote> 
     <blockquote><pre>YES</pre> <pre>YES</pre></blockquote> 
     <blockquote>NO</blockquote> 
</div></body> 

XPath表達式求值和所選擇的節點被複制到輸出:

<blockquote> 
    <pre>YES</pre> 
</blockquote> 
<blockquote> 
    <pre>YES</pre> 
    <pre>YES</pre> 
</blockquote> 
5
//blockquote[pre][count(pre)=count(*)] 
+0

不知道我們是否需要點斜槓 – 2012-07-11 19:29:41

+1

我不認爲他們是需要的。 – BoltClock 2012-07-11 19:30:37

相關問題