2012-05-10 79 views
2

我有以下XML代碼:特定範圍內獲得不同的屬性值

<!-- language: xml --> 
<Stats> 
    <Stat> 
    <Data Name="Value">63.76</Data> 
    <Data Name="Entity">first</Data> 
    </Stat> 
    <Stat> 
    <Data Name="Value">51.23</Data> 
    <Data Name="Entity">second</Data> 
    </Stat> 
    <Stat> 
    <Data Name="Value">46.1</Data> 
    <Data Name="Entity">third</Data> 
    </Stat> 
    <Stat> 
    <Data Name="Value">61.21</Data> 
    <Data Name="Entity">first</Data> 
    </Stat> 
</Stats> 

我要過濾只有在「數據[@名稱=」實體「。使用XPath:/Stats/Stat/Data[@Name="Entity"]回報: 第一 第二 第三 第一

但我想要的結果是唯一的。所以我只得到: 第一個 第二個 第三個

編輯:我需要這個爲xpath版本1.0工作。

+0

Bouke Groeneschei j:我的回答有用嗎?或者您還有問題嗎? –

+0

duplicate-> http://stackoverflow.com/questions/3016929/selecting-unique-records-in-xslt-xpath – rt2800

+0

我看過這篇文章,但是 - 我不認爲這是重複的。 XML代碼中有: 63.76 第一 我的XML代碼: <數據名稱= 「值」> 63.76 <數據名稱= 「實體」>第一個

回答

3

使用這個XPath 1.0表達式

/Stats/Stat 
    [Data/@Name='Entity' 
    and 
    not(Data[@Name='Entity'] = following-sibling::Stat/Data[@Name = 'Entity']) 
    ] 
    /Data[@Name='Entity'] 

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= 
     "/Stats/Stat 
      [Data/@Name='Entity' 
      and 
      not(Data[@Name='Entity'] = following-sibling::Stat/Data[@Name = 'Entity']) 
      ] 
      /Data[@Name='Entity'] 
     "/> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被應用上以下XML文檔(由cor recting的形成非共以及提供的文本):

<Stats> 
    <Stat> 
    <Data Name="Value">63.76</Data> 
    <Data Name="Entity">first</Data> 
    </Stat> 
    <Stat> 
    <Data Name="Value">51.23</Data> 
    <Data Name="Entity">second</Data> 
    </Stat> 
    <Stat> 
    <Data Name="Value">46.1</Data> 
    <Data Name="Entity">third</Data> 
    </Stat> 
    <Stat> 
    <Data Name="Value">61.21</Data> 
    <Data Name="Entity">first</Data> 
    </Stat> 
</Stats> 

以上的XPath表達式,並且所述選擇的節點被複制到輸出:

<Data Name="Entity">second</Data> 
<Data Name="Entity">third</Data> 
<Data Name="Entity">first</Data> 

:如果只是需要文本節點(「第一」,「第二」和「第三」),只需使用此單個XPath表達式:

/Stats/Stat 
    [Data/@Name='Entity' 
    and 
    not(Data[@Name='Entity'] = following-sibling::Stat/Data[@Name = 'Entity']) 
    ] 
    /Data[@Name='Entity'] 
     /text() 
+0

Just awesome!非常感謝您的快速和準確的答覆。我一直在尋找這個很長一段時間。特別是最後一個注意事項 - XSLT是一個巨大的獎勵! –

+0

@BoukeGroenescheij:不客氣。是的,XPath和XSLT都是迷人的,強大而優雅的語言。 –

3

你需要說哪個版本的XPath。在XPath 2.0,是微不足道:

distinct-values(/Stats/Stat/Data/@Name) 
+0

謝謝。你是對的 - 對不起,我需要XPath 1.0。 –

+1

順便說一句,上面的代碼沒有給出想要的結果,因爲它返回值和實體。將它更改爲:distinct-values(/ Stats/Stat/Data [@ Name ='Entity])它的工作原理 - 現在我需要將其轉換爲XPath版本1.0 ... –