0

I am wondering if you could help me out. I am trying to use TFHpple to parse HTML data using Swift 1.2, but I am having issues working out the XPath expression. I am getting the following error:

Optional(https://www.rac.co.uk/buying-a-car/car-passport/report/buyer/purchase/?BuyerVrm=yg06dxt)

XPath error : Invalid expression
//td[@class=‘CarMiniProfile-TableHeader’]/td

XPath error : Invalid expression //td[@class=‘CarMiniProfile-TableHeader’]/td

2016-03-01 16:26:23.645 CarCamera[1974:63769] Unable to evaluate XPath. empty nodes!!

The XPath code I am trying to use is

var XPathString = "//td[@class=‘CarMiniProfile-TableHeader’]/td"

The information I am trying to get is the make and model of the car entered.

<div>
  <table class="CarMiniProfile-table">
    <tbody>
      <tr class="CarMiniProfile-tableFirstRow">
        <td class="CarMiniProfile-tableHeader">
          Make
        </td>
        <td>
          FIAT
        </td>
      </tr>
      <tr>
        <td class="CarMiniProfile-tableHeader">
          Model
        </td>
        <td>
          PUNTO SPORTING M-JET
        </td>
      </tr>
      <tr>
        <td class="CarMiniProfile-tableHeader">
          Colour
        </td>
        <td>
           BLUE
        </td>
      </tr>
      <tr>
        <td class="CarMiniProfile-tableHeader">
          Year
        </td>
        <td>
          2006
        </td>
      </tr>
      <tr>
        <td class="CarMiniProfile-tableHeader">
          Engine Size
        </td>
        <td>
          1910 cc
        </td>
      </tr>
    </tbody>
  </table>
</div>

Swift code:

var newURL = NSURL(string: "https://www.rac.co.uk/buying-a-car/car-passport/report/buyer/purchase/?BuyerVrm=\(numberplate)")
var htmlData: NSData = NSData(contentsOfURL: newURL!)!
var Parser = TFHpple(HTMLData: htmlData)
var XPathString = "//td[@class=‘CarMiniProfile-TableHeader’]/td"
var nodes = Parser.searchWithXPathQuery(XPathString) as NSArray

        if(nodes.count == 0 ){
            println("empty nodes!!")
        }else{
            for element in nodes
            {
                println(element.content)
            }
        }
zx485
  • 28,498
  • 28
  • 50
  • 59
Bobby
  • 11
  • 5
  • Perhaps this is because you are using characters that are not interpreted as quotes, `’` instead of `'` or because your XPath engine does not support predicates (between `[` and `]`). – Mathias Müller Mar 01 '16 at 16:38
  • 1
    Other than the curly quotes, your XPath is also incorrect, Try: `var XPathString = "//td[@class='CarMiniProfile-TableHeader']"` – Code Different Mar 01 '16 at 16:48
  • Ill give it a try now, thanks for pointing out the wrong quotes. Is the TD not needed on the end? And would this return the word make or fiat in this case – Bobby Mar 01 '16 at 16:59
  • think ive worked it out, using the XPath as //table[@class='CarMiniProfile-table']//tr[2]/td[2] and changing the tr[] value to between 1-5 returns the information im after. this works on an online xpath evaluater but would it work in tfhpple? – Bobby Mar 01 '16 at 18:53

1 Answers1

0

First: in your sample you have:

 <td class="CarMiniProfile-tableHeader">

but you were querying for

 //td[@class=‘CarMiniProfile-TableHeader’] 

(notice the capital 'T' in TableHeader). xpath is case sensitive.

Second: by querying for //td[@class=‘CarMiniProfile-TableHeader’]/td you imply that you have a 'td' element inside the outer td, whereas they are siblings.

There are a number of ways to get the make and model here a couple

  • option 1: go one level up and select from the TR //tr/td[2] will return you a list of nodes (every second td-child of tr)
  • option 2: use the sibling axis: //td/following-sibling::td[1]
Daniele
  • 1,053
  • 10
  • 17