scinfu / SwiftSoup

SwiftSoup: Pure Swift HTML Parser, with best of DOM, CSS, and jquery (Supports Linux, iOS, Mac, tvOS, watchOS)
https://scinfu.github.io/SwiftSoup/
MIT License
4.52k stars 345 forks source link

discussion: How can I extract content of value at XPath using SwiftSoup? #176

Closed TyrfingMjolnir closed 2 years ago

TyrfingMjolnir commented 3 years ago

discussion: How can I extract content of value at XPath using SwiftSoup?

As pr example: /html/body/table/tbody/tr[18]/td[2]/table/tbody/tr[9]/td[2]/table/tbody/tr[2]/td

MuhammedZakir commented 3 years ago

There is no XPath support. Use CSS selectors instead.

html body tabe tbody tr:nth-child(18) td:nth-child(2) ...

If you want to select a child element, use > [2]. If you want to select a descendant, use space (like I did) [3]. See [4] for CSS selectors' overview.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child [2] http://css.maxdesign.com.au/selectutorial/selectors_child.htm [3] http://css.maxdesign.com.au/selectutorial/selectors_descendant.htm [4] https://www.w3schools.com/cssref/css_selectors.asp

Edit: Internet Archive - https://web.archive.org/web/20201109041508/http://css.maxdesign.com.au/selectutorial/.

TyrfingMjolnir commented 2 years ago

How would I count the number of children and say I would like to have 3rd child from the bottom of the document: nth-child( childcount - 2 )

scinfu commented 2 years ago

@TyrfingMjolnir try using elements.size() - 2

func testFilter()throws {
        let h: String = "<p>Excl</p><div class=headline><p>Hello</p><p>There</p></div><div class=headline><h1>Headline</h1></div>"
        let doc: Document = try SwiftSoup.parse(h)
        let els: Elements = try doc.select(".headline").select("p")
        XCTAssertEqual(2, els.size())
        try XCTAssertEqual("There", els.get(els.size()-1).text())
    }