2009-12-30 85 views
55

鑑於這種XML:使用XPath,如何根據文本內容和屬性值選擇節點?

<DocText> 
<WithQuads> 
    <Page pageNumber="3"> 
     <Word> 
      July 
      <Quad> 
       <P1 X="84" Y="711.25" /> 
       <P2 X="102.062" Y="711.25" /> 
       <P3 X="102.062" Y="723.658" /> 
       <P4 X="84.0" Y="723.658" /> 
      </Quad> 
     </Word> 
     <Word> 
     </Word> 
     <Word> 
      30, 
      <Quad> 
       <P1 X="104.812" Y="711.25" /> 
       <P2 X="118.562" Y="711.25" /> 
       <P3 X="118.562" Y="723.658" /> 
       <P4 X="104.812" Y="723.658" /> 
      </Quad> 
     </Word> 
    </Page> 
</WithQuads> 

我想找到具有的「七一」和四核/ P1/X屬性大於90。因此,文本在這種情況下的節點,它不應該返回任何匹配。但是,如果我使用GT(>)或LT(<),我會在第一個單詞元素上找到一個匹配項。如果我使用eq(=),則無法匹配。

所以:

//Word[text()='July' and //P1[@X < 90]] 

將返回true,這將

//Word[text()='July' and //P1[@X > 90]] 

如何正確約束這對P1爲X屬性?

另外,假設我有多個頁面元素,用於不同的頁碼。我如何額外限制上述搜索以找到具有text()='July', [email protected] < 90和?@pageNumber=3的節點?

+0

對於每個讀者來說這個特殊的XML可能並不是很明顯的一個重要事情,那就是因爲這個XML使用混合內容模型,所以很難與XPath匹配元素。最近我遇到了這個問題,並且正在使用我的XPath生鏽,我得出的結論是,在下面找到Michael Kay的答案之前,無法匹配混合內容元素。我一直無法找到任何其他參考,討論混合內容和XPath的缺陷。 –

+0

您的問題回答了我的問題。在XPath中對字符串使用「單引號」非常重要,而不是「雙引號」。這真的很重要。感謝您的線索。 –

回答

66

通常我會考慮在XPath中使用前綴不正確的氣味。

試試這個: -

/DocText/WithQuads/Page/Word[text()='July' and Quad/P1/@X > 90] 

你的問題是,你使用的在文檔的開頭開始回來,並開始追捕任何P1因此它永遠是真實的//P1[@X < 90]。同樣//P1[@X > 90]總是如此。

+1

我很驚訝這實際上是因爲Michael Kay的回答中解決的空白問題而起作用的。我在兩個不同的XPath評估器中嘗試了這個答案,但它無法匹配。一旦我用「正常化空間」切換到謂詞,我就成功匹配了。 –

23

除了「//」問題之外,這個XML是混合內容的一個非常奇怪的用法。如果任何子文本節點與7月完全相同,則謂詞text()='July'將匹配該元素,由於周圍有空白,在您的示例中這不是真的。根據源XML的確切定義,我會選擇[text()[normalize-space(.)='July'] and Quad/P1/@X > 90]

+0

謝謝你,邁克爾。我在想空白空間......我在粘貼到堆棧溢出之前對樣本進行了格式化,但是我的源代碼XML是「緊密」的。當我對格式化版本運行xpath時,確實無法正常工作。我會嘗試使用normalize-space(。) –

相關問題