2012-06-28 75 views
1

如何編寫xpath查詢以匹配以下XML代碼片段中的<subitem>元素?具有與祖先相同屬性值的項目的Xpath

具體而言,我想匹配任何具有與名稱的「name」屬性值相匹配的「name」屬性的元素。在<root><subitem>之間可能有任意數量的祖先。

<root name="xyz"> 
    <anything> 
    <subitem name="xyz" /> 
    </anything> 
</root> 

我的目標是編寫一個PMD規則發現)使用不同類的不是類的聲明是在Logger.getLogger的情況下(

回答

1

使用此XPath表達式

//*[@name = /*/@name] 

這將選擇的任何元素(包括命名root所述頂部元件),其name屬性具有相同的字符串值作爲該name屬性的的頂部元素。當根據提供的XML文檔評估該XPath表達式時,選擇了兩個元素 - rootsubitem

我認爲只有這兩個的第二個元素是想要的。對於這一點,使用下面的XPath表達式

//*/*[@name = /*/@name] 

XSLT - 基於驗證

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

<xsl:template match="/"> 
    <xsl:copy-of select="//*/*[@name = /*/@name]"/> 
======== 
    <xsl:copy-of select="//*[@name = /*/@name]"/> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<root name="xyz"> 
    <anything> 
     <subitem name="xyz" /> 
    </anything> 
</root> 

這兩個XPath表達式是e估價和選擇的節點被複制到輸出:

<subitem name="xyz"/> 
======== 
    <root name="xyz"> 
    <anything> 
     <subitem name="xyz"/> 
    </anything> 
    </root> 
    <subitem name="xyz"/> 
+1

不錯。我不敢相信我沒有注意到它也選擇了'root'。 –

0

//*[@name=(ancestor::*/@name)]

這應該做的招。我會讀它爲「查找具有相同name祖先的所有節點。」


編輯(加了第二個,它仍然選擇太多)

問題的編輯後:

//*[@name=(/@name)]

該讀作「查找所有節點是與根節點具有相同的name「。需要注意的是根節點可能不是你認爲它是(你要匹配名爲root,不root最頂層節點),你可能需要實現它作爲

//*[@name=(/root/@name)]//*[@name=(/*/@name)]


這將選擇兩個元素,你subitemroot這是不想要的,你只需要選擇那些不在最上方(是root後代)節點。感謝Dimitre Novatchev爲此。

//*/*[@name=(/*/@name)]

+0

哦,你編輯的問題,現在這個查詢會發現更多的是你想要的。要編輯。 –

+1

謝謝,這讓我走上了正軌! – bluskies

+0

@DimitreNovatchev真的嗎?我對此非常感興趣,因爲我使用內部IntelliJ XPath支持和/或[xmlstarlet](http://xmlstar.sourceforge.net/)來評估我的XPath表達式,並且沒有報告任何警告或錯誤。有一個工具來驗證我的表達式並指出我的語法錯誤真是太棒了。 –

相關問題