2008-12-02 29 views
16

Biểu thức XPath mà tôi sẽ sử dụng để lấy chuỗi sau 'HarryPotter:' cho mỗi cuốn sách là gì.Cách áp dụng hàm XPath 'substring-after'

tức là. Với XML này:

<bookstore> 
<book> 
    HarryPotter:Chamber of Secrets 
</book> 
<book> 
    HarryPotter:Prisoners in Azkabahn 
</book> 
</bookstore> 

tôi sẽ nhận lại: một cái gì đó

Chamber of Secrets 
Prisoners in Azkabahn 

Tôi đã cố gắng như thế này:

/bookstore/book/text()[substring-after(. , 'HarryPotter:')] 

Tôi nghĩ rằng cú pháp của tôi là không chính xác ...

Trả lời

22

Trong XPath 2.0 này có thể được sản xuất bởi một biểu thức XPath duy nhất:

            /*/*/substring-after(., 'HarryPotter:')

Ở đây chúng ta đang sử dụng các tính năng rất mạnh mẽ của XPath 2.0 mà ở phần cuối của một đường dẫn của các bước vị trí chúng ta có thể đặt một hàm và hàm này sẽ được áp dụng trên tất cả các nút trong tập kết quả hiện tại.

Trong XPath 1.0, không có tính năng như vậy và điều này không thể được thực hiện trong một biểu thức XPath.

Chúng ta có thể thực hiện một chuyển đổi XSLT như sau:

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

    <xsl:template match="/"> 
     <xsl:for-each select="/*/*[substring-after(., 'HarryPotter:')]"> 
     <xsl:value-of select= 
     "substring-after(., 'HarryPotter:')"/> 
     <xsl:text>&#xA;</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Khi áp dụng trên tài liệu XML gốc:

 
<bookstore> 
    <book> HarryPotter:Chamber of Secrets </book> 
    <book> HarryPotter:Prisoners in Azkabahn </book> 
</bookstore> 

chuyển đổi này tạo ra kết quả mong muốn:

Phòng Bí mật
Tù nhân tại Azkabahn

+0

Ngược lại, XPath 1.0 * có * có chuỗi con sau: http://www.w3.org/TR/xpath/#function-substring-after –

+6

@ Josh-Stodola, Tôi đã nói ở đâu rằng nó không có hàm substring-after()? XPath 1.0 * không cho phép * một hàm được chỉ định làm bước vị trí, hãy quan tâm xem đây có phải là chuỗi con sau() hay bất kỳ hàm nào khác không. Vui lòng hoàn nguyên * ghi chú * không đúng của bạn! –

+6

Josh không biết Dimitre là ai :) – grantwparks

5

Trong XML của bạn, bạn không có không gian giữa Harry Potter nhưng trong XQuery của bạn, bạn đã có một không gian. Chỉ cần làm cho nó phù hợp và mau, bạn sẽ nhận được dữ liệu trở lại ...

Dim xml = <bookstore> 
        <book>HarryPotter:Chamber of Secrets</book> 
        <book>HarryPotter:Prisoners in Azkabahn</book> 
        <book>MyDummyBook:Dummy Title</book> 
       </bookstore> 

    Dim xdoc As New Xml.XmlDocument 
    xdoc.LoadXml(xml.ToString) 

    Dim Nodes = xdoc.SelectNodes("/bookstore/book/text()[substring-after(., 'HarryPotter:')]") 

    Dim Iter = Nodes.GetEnumerator() 
    While Iter.MoveNext 
     With DirectCast(Iter.Current, Xml.XmlNode).Value 
      Console.WriteLine(.Substring(.IndexOf(":") + 1)) 
     End With 
    End While 
+0

xin lỗi - chuỗi đó có một khoảng trống do nhầm lẫn ... Tôi đã sửa nó ngay bây giờ. Bạn thực hiện thao tác chuỗi trong VB (không phải trong XPath).Tôi đang cố gắng sử dụng biểu thức XPath là nhận được mọi thứ sau chuỗi 'HarryPotter:' trong mỗi nút được chọn. Bất kỳ ý tưởng? –

+0

không có XQuery ở đây ... chỉ là XPath. Ngoài ra, việc sử dụng chuỗi con sau() bên trong một biến vị ngữ khá rõ ràng là một sai lầm trong phần của OP, chứ không phải cái gì chúng ta muốn duy trì. – LarsH

4

Biểu thức XPath

/bookstore/book/text()[substring-after(. , 'HarryPotter:')] 

sẽ trả về một nút thiết lập với tất cả các nút văn bản có chứa giá trị "Harry Potter:". Để có được tiêu đề sách thành công "HarryPotter:" bạn cần phải đi qua tập hợp nút này và tìm nạp chuỗi con đó cho mỗi nút. Điều này có thể được thực hiện với chuỗi con sau nếu bạn đang sử dụng XSLT hoặc với chuỗi con và IndexOf nếu bạn đang sử dụng VB như được hiển thị bởi balabaster.

0

XPath:

substring-after(//book, 'Advertised:') 

Tôi hoàn toàn mới trong lĩnh vực này, nhưng đối với tôi, nó hoạt động ...!

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