2009-06-25 51 views
0

我有一個很大的XML集,我想運行一些xpath來製作一個更小的子集。 基本上,我有這種類型的佈局:xpath查詢幫助,試圖獲取更大的XML的子集

<root> 
    <item> 
    <collection1></collection1> 
    <collection2></collection2> 
    <collection3></collection3> 
    ... 
    <collection55></collection55> 
    <name>item name</name> 
    <timestamp>47398743598</timestamp> 
    <another1></another1> 
    <another2></another2> 
    ... 
    </item> 
    <item> 
    ... 
    </item> 
</root> 

換句話說,項目節點的堆,和很多我不關心其他垃圾節點。

我想運行一些的XPath,來獲取到:

<root> 
    <item> 
    <name>item name</name> 
    <timestamp>47398743598</timestamp> 
    </item> 
    <item> 
    ... 
    </item> 
</root> 

我目前這種類型的事情:

//項目/名稱

只得到名稱節點,

所以然後我一直在嘗試這種類型的東西:

//項目/名稱/父項::項目

它獲取名稱節點,它的父節點(這是項目節點),但也是名稱節點的所有兄弟節點,這正是我試圖避免!

任何幫助,將不勝感激

乾杯, 馬克

回答

4

第一關:你不能使用XPath獲得一個XML文件「歸結爲某件事」。你可以用它來選擇節點,就這些了。如果您想更改XML文檔,請使用XSLT。

這個表達式:

//item/name/parent::item 

沒有選擇「的名字節點,它的父」,它選擇<name>節點的父節點,而不是其他。

嚴格來說,它選擇所有<item>節點,它們恰好是<item>節點的子節點的<name>節點的父節點。當您考慮時,相當於只使用"//item"

沒有辦法選擇節點的結構。您只能選擇一個節點列表 - 一個節點集。然後,您可以遍歷這些節點並查找它們在文檔中的位置,但節點集本身是平坦的。

我認爲你需要更仔細地解釋你正在嘗試做什麼。我可以寫一個XSL轉換,做你似乎什麼打算,但除非我確信你打算什麼... ;-)

編輯:

這裏是一個簡約的XSLT 1.0的做法,將做到這一點。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="root | item | name | timestamp"> 
    <xsl:copy> 
     <xsl:apply-templates select="*" /> 
     <xsl:if test="count(*) = 0"> 
     <xsl:value-of select="text()" /> 
     </xsl:if> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="* | text()" /> 

</xsl:stylesheet> 

輸出爲您的樣品(壓痕礦):

<root>e 
    <item> 
    <name>item name</name> 
    <timestamp>47398743598</timestamp> 
    </item> 
    <item> 
    ... 
    </item> 
</root> 
0

您可以與or|)運算符嘗試://item/name|//item/timestamp

+0

這實際上只是返回名稱和時間戳節點,雖然它是我之後的東西,我會理想地喜歡它們包裹在他們的父節點節點 – Mark 2009-06-25 11:13:34

+0

對不起,我認爲主要問題是獲取子節點。不幸的是,使用單個XPath是不可能的;它只是選擇節點,並不修剪它們。您需要使用XSLT:選擇項目的一個模板,以及僅選擇名稱和時間戳的一個(或子表達式)。 – l0b0 2009-06-25 12:04:40

1

使用XSLT,這個模板添加到identity transform

<xsl:template match="item"> 
    <xsl:copy> 
     <xsl:apply-templates select="name | timestamp"/> 
    </xsl:copy> 
</xsl:template> 
1

託默勒格的答案是偉大的,如果你真的想要一個修整XML文檔,但有一點需要注意:他的選擇模板將複製任何名稱和時間戳記節點,而不僅僅是項目元素下面的那些節點。

然而,我懷疑你並不是真的想要一個精緻的XML文檔,你只需要每個項目的名稱和時間戳節點。根據您使用的語言,您應該能夠使用xpath爲您提供一個更小的節點集合。在僞代碼中:

  1. 爲「/ root/item」選擇xpath。這應該返回某種類型的列表。如果你提到了你的實現語言 ,我可以發佈一個簡單的代碼片段。
  2. 對於每個項目,請選擇時間戳和名稱標籤。沒有理由關心其他節點。

但是,如果您確定需要XML,請使用XSLT。