2012-09-27 21 views
1

給定以下結構,在XPATH中,我想選擇整個樹,但只包含第一個日期,因此排除所有其他日期。第一次日期之後的日期數量不是恆定的。有任何想法嗎?我的歉意是格式不正確。XPATH選擇整個樹只包括第一個

<A> 
    <B> 
     <DATE>04272011</DATE> 
     <C> 
      <D> 
       <DATE>02022011</DATE> 
      </D> 
      <D> 
       <DATE>03142011</DATE> 
      </D> 
     </C> 
    </B> 
</A> 

我appologies。

一個更好的例子

<NOTICES>

<SNOTE>

<DATE>01272011</DATE> 
    <ZIP>35807</ZIP> 
    <CLASSCOD>A</CLASSCOD> 
    <EMAIL> 
     <ADDRESS>address 1</ADDRESS> 
    </EMAIL> 
    <CHANGES> 
     <MOD> 
      <DATE>02022011</DATE> 
      <MODNUM>12345</MODNUM> 
      <EMAIL> 
       <ADDRESS>address 2</ADDRESS> 
      </EMAIL> 
     </MOD> 
     <MOD> 
      <DATE>03022011</DATE> 
      <MODNUM>56789</MODNUM> 
      <EMAIL> 
       <ADDRESS>address 3</ADDRESS> 
      </EMAIL> 
     </MOD> 
    </CHANGES> 
</SNOTE> 

</NOTICES>

我打破了一個大的XML文件到各個XML文件。我原來的XPATH語句是

/通知/ S注

每個單獨的XML文件看起來不錯,除了它拉在所有的日期:這是我想要的輸出。

<SNOTE>

<DATE>01272011</DATE> 
<ZIP>35807</ZIP> 
<CLASSCOD>A</CLASSCOD> 
<EMAIL> 
    <ADDRESS>address 1</ADDRESS> 
</EMAIL> 
<CHANGES> 
    <MOD> 
     <MODNUM>12345</MODNUM> 
     <EMAIL> 
      <ADDRESS>address 2</ADDRESS> 
     </EMAIL> 
    </MOD> 
    <MOD> 
     <MODNUM>56789</MODNUM> 
     <EMAIL> 
      <ADDRESS>address 3</ADDRESS> 
     </EMAIL> 
    </MOD> 
</CHANGES> 

</SNOTE>

+3

你能指定輸出,所以它更清楚嗎? – Anshu

+1

XPath 1.0或2.0? (XSLT,PHP ...)使用XPath的語言是什麼? – choroba

+1

這可能是一個好主意,告訴我們你想要完成什麼。有多種方式來解釋你在說什麼。一個似乎沒用,另一個需要比XPath更多的功能。 – LarsH

回答

3

XPath是查詢 XML文檔的語言,因此它不能改變文檔的結構(如插入/刪除/重命名節點)。

你需要的是一個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="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="DATE[preceding::DATE]"/> 
</xsl:stylesheet> 

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

<A> 
    <B> 
     <DATE>04272011</DATE> 
     <C> 
      <D> 
       <DATE>02022011</DATE> 
      </D> 
      <D> 
       <DATE>03142011</DATE> 
      </D> 
     </C> 
    </B> 
</A> 

通緝,正確的結果產生

<A> 
    <B> 
     <DATE>04272011</DATE> 
     <C> 
     <D/> 
     <D/> 
     </C> 
    </B> 
</A> 
1

如果「選擇整樹」你的意思是「選擇一組樹中的所有節點」(除了非第一次約會的元素),即可以做到:

"//node()[not(self::DATE) or not(preceding::DATE)]" 

然後,非第一<DATE>元件節點將不本身是在所選擇的節點集,但在第節點e選定的節點集(例如根節點,或<D>)仍然會有<DATE>後代。

如果您想要選擇樹(即根節點),或者更改它的版本,使得<D>元素沒有任何<DATE>子元素,則需要修改樹。 XPath無法自行修改XML樹。您需要XML轉換技術,例如XSLT或XML DOM庫。

+0

謝謝。我想從。有沒有辦法讓我發佈一個更好的例子來說明這個線程中的內容和原因? –

+1

@HammerTime:從''到''的所有內容都包含所有''元素,所以我認爲我們需要更清晰。發佈信息的最佳方式以及爲什麼要編輯原始問題。 (並用「@LarsH」添加評論讓我知道。) – LarsH

+0

我已更新我的原創以更好地描述我想要做的事情。我知道如何選擇一切,我知道如何選擇我想排除的日期。謝謝。 –