2011-07-01 24 views
18

Dưới đây là ba XML-câyXPath 1.0 gần nhất trước và/hoặc nút tổ tiên với một thuộc tính trong một XML Tree

(1)

<?xml version="1.0" encoding="UTF-8"?> 
<content> 
    <section id="1"> 
     <section id="2"/> 
     <section id="3"/> 
     <section id="9"/> 
    </section> 
    <section id="4"> 
     <section id="5"> 
      <section> 
       <bookmark/> <!-- here's the bookmark--> 
       <section id="6"> 
        <section id="7"> 
         <section id="8"/> 
        </section> 
       </section> 
      </section> 
     </section> 
    </section> 
</content> 

(2)

<?xml version="1.0" encoding="UTF-8"?> 
<content> 
    <section id="1"/> 
    <section id="2"> 
     <section id="9"> 
      <section id="10"> 
       <section id="11"/> 
      </section>    
     </section> 
     <section> 
      <section id="4"> 
       <section id="5"/> 
      </section>    
     </section> 
     <section/> 
     <bookmark/> <!-- here's the bookmark--> 
     <section id="6"> 
      <section id="7"> 
       <section id="8"/> 
      </section> 
     </section> 
    </section> 
</content> 

Các kết quả mong muốn trong cả hai trường hợp là số .

Với XSLT 1.0 và XPath 1.0 Tôi có thể hoặc là có được tổ tiên từ (1)

<xsl:value-of select="//bookmark/ancestor::*[@id][1]/@id"/> 

hoặc nút trước từ (2)

<xsl:value-of select="//bookmark/preceding::*[@id][1]/@id"/> 

Làm thế nào để tôi có được gần tổ tiên hoặc trước nút có id từ dấu trang của tôi?
Tôi cần một giá trị xsl: value-of khớp với cả hai trường hợp. Cảm ơn.

EDIT:

Giải pháp này cũng nên bao gồm cấu trúc này. Id mong muốn vẫn là .

(3)

<?xml version="1.0" encoding="UTF-8"?> 
<content> 
    <section id="1"> 
     <section id="2"/> 
     <section id="3"/> 
     <section id="9"/> 
    </section> 
    <section id="4"> 
     <section> 
      <section id="10"/> 
      <section id="5"/> 
      <section> 
       <bookmark/> <!-- here's the bookmark--> 
       <section id="6"> 
        <section id="7"> 
         <section id="8"/> 
        </section> 
       </section> 
      </section> 
     </section> 
    </section> 
</content> 
+8

Hình ảnh hiển thị tất cả các trục xpath: [pic] (http://nwalsh.com/docs/tutorials/xsl/xsl/graphics/axes.gif) – therealmarv

+1

Câu hỏi hay, +1. Xem câu trả lời của tôi cho biểu thức XPath một lớp mà chọn chính xác nút thuộc tính mong muốn trong cả ba trường hợp. :) –

Trả lời

22

Sử dụng:

(//bookmark/ancestor::*[@id][1]/@id 
| 
    //bookmark/preceding::*[@id][1]/@id 
    ) 
    [last()] 

Xác: Sử dụng XSLT như máy chủ của XPath, việc chuyển đổi sau:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:value-of select= 
    "(//bookmark/ancestor::*[@id][1]/@id 
    | 
    //bookmark/preceding::*[@id][1]/@id 
    ) 
    [last()]"/> 
</xsl:template> 
</xsl:stylesheet> 

khi áp dụng vào bất kỳ cung cấp ba tài liệu XML, tạo ra mong muốn, đúng kết quả:

5

Tôi mạnh mẽ recomment sử dụng XPath Visualizer để chơi với/learni ng XPath.

+2

+1 giải pháp rất đẹp – cordsen

+0

@cordsen: Bạn được chào đón. –

+0

@Dimitre Giải pháp rất tuyệt vời! +1 Sẽ sử dụng điều này. Cũng nhờ mẹo của bạn để sử dụng XPath Visualizer. – therealmarv

3

Hãy thử với:

<xsl:value-of 
    select="//bookmark/ancestor::*[1]/descendant-or-self::*[last()-1]/@id"/> 

Nó trả 5 cho cả tài liệu XML.

EDIT:

Trong điều kiện như vậy, bạn có thể sử dụng đơn giản xsl:choose:

<xsl:variable name="lastSibling" 
    select="//bookmark/preceding-sibling::*[1]"/> 
<xsl:choose> 
    <xsl:when test="$lastSibling"> 
     <xsl:value-of 
      select="$lastSibling/descendant-or-self::*[last()]/@id"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="//bookmark/ancestor::*[@id][1]/@id"/> 
    </xsl:otherwise> 
</xsl:choose> 

Một giải pháp chung:

<xsl:for-each 
    select="//section[following::bookmark or descendant::bookmark][@id]"> 
    <xsl:if test="position() = last()"> 
     <xsl:value-of select="./@id"/> 
    </xsl:if> 
</xsl:for-each> 
+0

Giải pháp của bạn hoạt động trong những trường hợp đặc biệt. Nhưng nếu tôi thêm nhiều phần hơn với id sau khi đánh dấu trên cả hai XML, giải pháp của bạn sẽ cho kết quả sai. Sẽ chỉnh sửa các ví dụ của tôi để có một số phần sau khi đánh dấu trang. – therealmarv

+0

@therealmarv: Đúng vậy. Tôi giả định cấu trúc cụ thể. Kiểm tra giải pháp thứ hai của tôi. –

+0

@therealmarv: sửa chữa 'last()' → '1' trong biến' lastSibling'. –

Các vấn đề liên quan