Search code examples
xmlxcodeswiftxpathtfhpple

XPath Expression not working/incorrect TFHpple SWIFT 1.2


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

Solution

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