2014-02-14 27 views
1

XSD架構,我有工作,要求無論是國際或國內的地址選擇一個節點:如何conditinally XPath中

"/mns:PhysicalAddress/mns:DomesticAddress/mns:City" 

"/mns:PhysicalAddress/mns:InternationalAddress/mns:City" 

它被用作參數在如XMLUtils.BuildField(Document doc, String xpath)中的Java方法中。

我知道我可以直接找到創建doc的Java對象,並使用自動生成的bean查詢元素,但我更喜歡保留在XPath的簡潔領域。這可能嗎?

如果是這樣,我該如何編寫一個XPath表達式選擇mns:City而不管它是國際還是國內地址?

注意:這在Java,而不是Javascript,HTML或XSLT,所以我不認爲<xsl:if>在這裏是相關的。

回答

2

你可以與發現,有父母一方所有城市去:

//mns:City[(parent::mns:DomesticAddress|parent::mns:InternationalAddress)] 

如果您還需要確保該地址是物理地址:

//mns:City[(parent::mns:DomesticAddress|parent::mns:InternationalAddress)[parent::mns:PhysicalAddress]] 

或者,不是反轉層次結構,你做一個*並檢查名稱:

/mns:PhysicalAddress/*[name()="mns:DomesticAddress" or name()="mns:InternationalAddress"]/mns:City 
+0

謝謝!你在那裏放的表達是否來自我原來的'xpath'中的單個'/ mns:City'?或者它是獨立的?我從來沒有見過這種「反向層次」,這就是爲什麼我問。 +1現在,我會接受,一旦我得到它的測試。 – WinWin

+0

它是獨立的(即將完全取代你當前的xpath)。我不相信反向層次結構是常見的。我只看到它用於這種場景,你需要在節點上做一些'或'。 –

+0

好吧,想出如何進入層次結構 - 參見最後一個例子。 –

2

根據你的XML的精確結構,

/mns:PhysicalAddress/*/mns:City 

可能是不夠的,如果太多,則清晰的選項可能只是用兩個選擇,你已經有了,由|分開拉:

/mns:PhysicalAddress/mns:DomesticAddress/mns:City | /mns:PhysicalAddress/mns:InternationalAddress/mns:City 

或略有更簡潔,但(在我看來)不太清楚:

/mns:PhysicalAddress/*[self::mns:DomesticAddress | self::mns:InternationalAddress]/mns:City 
+1

謝謝!這看起來比以前的建議更簡潔,我喜歡。通過*「只是使用你已經有的兩種選擇,用|」*分隔,你的意思是'「/ mns:PhysicalAddress/mns:DomesticAddress | mns:InternationalAddress/mns:City」'? – WinWin

+1

@WinWin如果你有XPath 2.0,那麼你可以執行'/ mns:PhysicalAddress /(mns:DomesticAddress | mns:InternationalAddress)/ mns:City',但是如果你限制爲1.0,那麼你必須將整個路徑(或者用'self ::'軸做一個技巧),我用一個例子編輯了答案。 –