2012-11-26 73 views
0

我需要使用XPath來根據多個子元素選擇不同的元素。如何使用XPath根據多個子元素選擇不同的元素?

我有一些這樣的XML:

<Cars> 
    <Car> 
    <Make>SuperCar</Make> 
    <Year>2009</Year> 
    </Car> 
    <Car> 
    <Make>SuperCar</Make> 
    <Year>2010</Year> 
    </Car> 
    <Car> 
    <Make>AwesomeCar</Make> 
    <Year>2010</Year> 
    </Car> 
    <Car> 
    <Make>SuperCar</Make> 
    <Year>2009</Year> 
    </Car> 
</Cars> 

我需要使用XPath(我限於XPath 1.0中),以只選擇不同的元件,其中,不同的是由兩個MakeYear定義。

在上面的例子中,這意味着返回所有的Car對象,除了最後一個(因爲這是第一個Car的副本)。

在典型情況下(即其中的對象是由一個鍵字段標識)我會使用XPath與此類似:

/*/Car[not(./Id/text()=following-sibling::Car/Id/text())] 

不過,我不能完全解決如何這個適應正確使用多個字段。

我認爲是這樣的:

/*/Car[not(./Make/text()=following-sibling::Car/Make/text() 
    and ./Model/text()=following-sibling::Car/Model/text())] 

但是,檢查是否Make在任何地方使用,如果Model任何地方使用,無需確保他們不一定在同一Car使用。例如,它錯誤地排除從下面的示例XML第一Car

<Cars> 
    <Car> 
    <Make>SuperCar</Make> 
    <Year>2009</Year> 
    </Car> 
    <Car> 
    <Make>SuperCar</Make> 
    <Year>2010</Year> 
    </Car> 
    <Car> 
    <Make>AwesomeCar</Make> 
    <Year>2009</Year> 
    </Car> 
</Cars> 

任何想法?

+0

你也許可以用''和'鍵()'函數來做到這一點。 –

回答

0

下面的XPath查詢返回不同的車的基礎上,製作和年(您在使用XML爲例):

/*/Car[not(./Make/text()=preceding-sibling::Car/Make/text() and ./Year/text()=preceding-sibling::Car/Year/text())] 

檢查前面的兄弟姐妹更明顯,因爲它們已經被「索引」。上面的查詢提供了以下的輸出:

<Car> 
    <Make>SuperCar</Make> 
    <Year>2009</Year> 
</Car> 
<Car> 
    <Make>SuperCar</Make> 
    <Year>2010</Year> 
</Car> 
<Car> 
    <Make>AwesomeCar</Make> 
    <Year>2010</Year> 
</Car> 
+0

欣賞嘗試,但不幸的是它不會工作。如果您在開始時添加了「{AwesomeCar,2009}」Car「,您的查詢將無效排除」{AwesomeCar,2010}「。原因是'先行兄弟'條款不是(我不認爲可以)強制同時指同一個兄弟姐妹。這意味着XPath讀取爲(任何兄弟擁有Make)或(任何兄弟擁有Year)而非預期(任何兄弟擁有Make和Year)。這方面的一個例子是http://www.xpathtester.com/saved/8706004d-076d-420d-b523-f54b9f7fff78(點擊測試查看輸出)。 –