2013-10-07 73 views
0

我有這樣的XML。它由外部提供,不能更改:獲取只有一個祖先節點的值

<locations> 
    <country iso_code="CA"> 
    <name>Canada</name> 
    <state abbreviation="AB"> 
     <name>Alberta</name> 
     <city> 
     <name>Leduc</name> 
     <location id="1"/> 
     </city> 
    </state> 
    <state abbreviation="BC"> 
     <name>British Columbia</name> 
     <city> 
     <name>Abbotsford</name> 
     <location id="2"/> 
     <location id="3"/> 
     </city> 
    </state> 
    </country> 
    <country iso_code="US"> 
    <name>United States</name> 
    <state abbreviation="AZ"> 
     <name>Arizona</name> 
     <city> 
     <name >Wikiup</name> 
     <location id="1"/> 
     </city> 
    </state> 
    </country> 
</locations> 

我的XSL是這樣的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" encoding="iso-8859-1"/> 
<xsl:strip-space elements="*" /> 
    <xsl:template match="/"> 
    <xsl:for-each select="//location[@id]"> 
     <xsl:call-template name="location"/> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="location"> 
    <xsl:value-of select="@id"/>, 
    <xsl:value-of select="ancestor::city[1]"/>, 
    <xsl:value-of select="ancestor::state[1]"/>, 
    <xsl:value-of select="ancestor::state[1]/@abbreviation"/>, 
    <xsl:value-of select="ancestor::country[1]"/>, 
    <xsl:value-of select="ancestor::country[1]/@iso_code"/>, 
    </xsl:template> 

</xsl:stylesheet> 

當我運行xsltproc的,我得到這個輸出(I拿出多餘的線條,使之花冤枉錢) :

1,Leduc,AlbertaLeduc,AB,CanadaAlbertaLeducBritish ColumbiaAbbotsford,CA, 
2,Abbotsford,British ColumbiaAbbotsford,BC,CanadaAlbertaLeducBritish ColumbiaAbbotsford,CA, 
3,Abbotsford,British ColumbiaAbbotsford,BC,CanadaAlbertaLeducBritish ColumbiaAbbotsford,CA, 
...etc... 

問題是,當我做的祖先[1] ::它拉了所有的ancesotors,而不是僅僅是一個我在尋找的值。

這裏是輸出應該是什麼樣子:

1,Leduc,Alberta,AB,Canada,CA, 
2,Abbotsford,British Columbia,BC,Canada,CA, 
3,Abbotsford,British Columbia,BC,Canada,CA, 
...etc... 

我嘗試使用../../。符號並得到相同的結果。我玩了一些其他的符號,它要麼不工作,要麼再次結束這些連接的值。

如何僅將直接父級的值傳遞給正在處理的節點,而不是所有級別的值?

希望我在這裏使用正確的術語。這是我第一次使用XSL進行一次性項目。

店裏的網絡傢伙也被難倒了。他們不經常使用XSL。

回答

1

如果您認爲XML是盒子,<value-of>將選定的盒子和它在其中找到的所有盒子解包,將它們丟棄並將盒子中的實際內容留給您。這些是文本節點。屬性也會被扔掉,它們是粘在盒子上的標籤。

<value-of select="ancestor::state">的情況下,它解開<state>框並在框內找到兩個框,<name>框和<city>框。因爲你使用的是<strip-space elements="*">,它也會拋棄所有的空白「泡沫包裝」,否則它會保留。它繼續取消裝箱並在<name>框中找到「Alberta」,在<city>框中找到另外兩個框:A <name><location>框。

這樣一來,比賽繼續:內部剛剛拆箱<name>中,發現Leduc並保持該旁邊Alberta,但它並沒有發現在<location>框中輸入任何內容。現在,沒有什麼可以解開的。所以我們留下一堆紙板和泡沫包裝廢棄物,其實際含量爲AlbertaLeduc(粘合在一起爲AlbertaLeduc)。

這裏是你的代碼的建議改進:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="iso-8859-1"/> 
    <xsl:strip-space elements="*" /> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="//location[@id]"/> 
    </xsl:template> 

    <xsl:template match="location"> 
    <xsl:value-of select="@id"/>, 
    <xsl:value-of select="ancestor::city[1]/name"/>, 
    <xsl:value-of select="ancestor::state[1]/name"/>, 
    <xsl:value-of select="ancestor::state[1]/@abbreviation"/>, 
    <xsl:value-of select="ancestor::country[1]/name"/>, 
    <xsl:value-of select="ancestor::country[1]/@iso_code"/>, 
    </xsl:template> 

</xsl:stylesheet> 
+0

由於負荷!我已經完成了與修復相同的代碼,即:不帶模板,但這只是我發佈當時代碼之前發生的一次顛簸。就像我說的那樣,這是一次性的,我不會使用xsl。對我而言,缺失的部分是/名稱以獲得節點的價值! – user2855855

+0

我很高興它適合你!如果這回答你的問題,你可以通過點擊複選標記來接受它嗎? –

相關問題