2012-05-02 21 views
7

chapters ile bir XML belgesine ve sections iç içe geçmiş. Herhangi bir bölüm için ilk ikinci düzey bölüm atasını bulmaya çalışıyorum. ancestor-or-self eksenindeki sonraki bölümdür. sözde kod:xpath ile sonuncu düğümü bulun

<chapter><title>mychapter</title> 
    <section><title>first</title> 
    <section><title>second</title> 
     <more/><stuff/> 
    </section> 
    </section> 
</chapter> 

benim seçici: Elbette

<xsl:apply-templates 
    select="ancestor-or-self::section[last()-1]" mode="title.markup" /> 

kadar çalışıyor geçen() - 1 tanımlı değil (akım düğüm first bölümdür).

Geçerli düğüm second bölümünün altındaysa, second başlığını istiyorum. Aksi takdirde first başlığını istiyorum.

+0

DocBook'u kullanmaya devam. –

cevap

4

Bu konudaki xpath değiştirin:

ancestor-or-self::section[position()=last()-1 or count(ancestor::section)=0][1] 

Zaten biri hariç tüm durumlarda doğru düğümü bulabilirsiniz yana, ben de seçin first bölüm (or count(ancestor::section)=0) bulmak ve için xpath güncellenmiş ([1]) ilk eşleşmeyi (ancestor-or-self eksenini kullandığımız için ters belge sırasına göre).

(ancestor-or-self::section[position() > last() -2])[last()] 

Bu section adlı muhtemelen ilk iki üstteki atalarının son seçer:

+0

Bu işe yarıyor - teşekkürler. Çözümünüzü denedikten sonra, bunu basitleştirebileceğimi düşündüm, ancak her zaman geçerli bölümü seçiyor gibi görünüyor. atası ya da öz :: d: bölüm [son() - 1 ya da son()] [1] ' – Tim

+0

@Tim' ata-or-ben :: bölüm [last() - boole (ata :: bölüm) ] [1] ' –

+0

@Aleh, zarif çözüm! – Tim

2

Burada kısa ve daha verimli bir çözüm olduğunu. Eğer böyle bir atasözü varsa, o zaman kendisi sondur. Burada

tam bir dönüşüm şudur: Bu dönüşüm, aşağıdaki belgeye
uygulanır

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

<xsl:template match="section"> 
    <xsl:value-of select="title"/> 
    <xsl:text> --> </xsl:text> 

    <xsl:value-of select= 
    "(ancestor-or-self::section[position() > last() -2])[last()]/title"/> 
    <xsl:text>&#xA;</xsl:text> 
    <xsl:apply-templates/> 
</xsl:template> 

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

(Resim göre, ancak ilave daha fazla iç içe section elemanları):

<chapter> 
    <title>mychapter</title> 
    <section> 
     <title>first</title> 
     <section> 
      <title>second</title> 
      <more/> 
      <stuff/> 
     <section> 
      <title>third</title> 
     </section> 
     </section> 
    </section> 
</chapter> 

doğru sonuçlar üretildi:

first --> first 
second --> second 
third --> second