2012-05-02 25 views
7

Tôi có tài liệu XML với chapters và lồng nhau sections. Tôi đang cố gắng tìm, cho bất kỳ phần nào, tổ tiên phần thứ hai cấp đầu tiên. Đó là phần tiếp theo đến cuối cùng trong trục ancestor-or-self. pseudo-code:tìm nút tiếp theo đến cuối cùng với xpath

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

chọn của tôi:

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

Dĩ nhiên mà làm việc cho đến khi cuối cùng() - 1 không được định nghĩa (nút hiện nay là phần first).

Nếu nút hiện tại ở dưới phần second, tôi muốn tiêu đề second. Nếu không, tôi muốn tiêu đề first.

+0

Đặc biệt sử dụng DocBook. –

Trả lời

4

Thay xpath của bạn với điều này:

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

Vì bạn đã có thể tìm thấy các nút bên phải trong mọi trường hợp trừ một, tôi cập nhật xpath của bạn để cũng tìm ra first phần (or count(ancestor::section)=0), và sau đó chọn ([1]) khớp đầu tiên (theo thứ tự tài liệu ngược lại, vì chúng tôi đang sử dụng trục ancestor-or-self).

+0

Điều đó hoạt động - cảm ơn. Sau khi thử giải pháp của bạn, tôi nghĩ tôi có thể đơn giản hóa nó với điều này, nhưng có vẻ như luôn luôn chọn phần hiện tại. 'tổ tiên-hoặc-tự :: d: phần [last() - 1 hoặc last()] [1]' – Tim

+0

@Tim 'tổ tiên hoặc tự :: phần [last() - boolean (tổ tiên :: phần) ] [1] ' –

+0

@ Aleh, giải pháp thanh lịch! – Tim

2

Dưới đây là một giải pháp ngắn hơn và hiệu quả hơn:

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

này lựa chọn cuối cùng của hai tổ tiên trên cùng có thể là lần đầu tiên tên là section. Nếu chỉ có một tổ tiên như vậy, thì chính nó là người cuối cùng.

Đây là một chuyển đổi hoàn toàn:

<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> 

Khi chuyển đổi này được áp dụng trên các tài liệu sau đây (dựa trên cung cấp, nhưng nói thêm lồng nhau hơn section yếu tố):

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

kết quả chính xác được sản xuất:

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