prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Tags <xml> are hidden from result titles
  
  
  </issue>
  <code>
  [start of searx/engines/xpath.py]
  1 from lxml import html
  2 from urllib import urlencode, unquote
  3 from urlparse import urlparse, urljoin
  4 from lxml.etree import _ElementStringResult, _ElementUnicodeResult
  5 from searx.utils import html_to_text
  6 
  7 search_url = None
  8 url_xpath = None
  9 content_xpath = None
  10 title_xpath = None
  11 suggestion_xpath = ''
  12 results_xpath = ''
  13 
  14 # parameters for engines with paging support
  15 #
  16 # number of results on each page
  17 # (only needed if the site requires not a page number, but an offset)
  18 page_size = 1
  19 # number of the first page (usually 0 or 1)
  20 first_page_num = 1
  21 
  22 
  23 '''
  24 if xpath_results is list, extract the text from each result and concat the list
  25 if xpath_results is a xml element, extract all the text node from it
  26    ( text_content() method from lxml )
  27 if xpath_results is a string element, then it's already done
  28 '''
  29 
  30 
  31 def extract_text(xpath_results):
  32     if type(xpath_results) == list:
  33         # it's list of result : concat everything using recursive call
  34         if not xpath_results:
  35             raise Exception('Empty url resultset')
  36         result = ''
  37         for e in xpath_results:
  38             result = result + extract_text(e)
  39         return result.strip()
  40     elif type(xpath_results) in [_ElementStringResult, _ElementUnicodeResult]:
  41         # it's a string
  42         return ''.join(xpath_results)
  43     else:
  44         # it's a element
  45         return html_to_text(xpath_results.text_content()).strip()
  46 
  47 
  48 def extract_url(xpath_results, search_url):
  49     url = extract_text(xpath_results)
  50 
  51     if url.startswith('//'):
  52         # add http or https to this kind of url //example.com/
  53         parsed_search_url = urlparse(search_url)
  54         url = parsed_search_url.scheme + url
  55     elif url.startswith('/'):
  56         # fix relative url to the search engine
  57         url = urljoin(search_url, url)
  58 
  59     # normalize url
  60     url = normalize_url(url)
  61 
  62     return url
  63 
  64 
  65 def normalize_url(url):
  66     parsed_url = urlparse(url)
  67 
  68     # add a / at this end of the url if there is no path
  69     if not parsed_url.netloc:
  70         raise Exception('Cannot parse url')
  71     if not parsed_url.path:
  72         url += '/'
  73 
  74     # FIXME : hack for yahoo
  75     if parsed_url.hostname == 'search.yahoo.com'\
  76        and parsed_url.path.startswith('/r'):
  77         p = parsed_url.path
  78         mark = p.find('/**')
  79         if mark != -1:
  80             return unquote(p[mark + 3:]).decode('utf-8')
  81 
  82     return url
  83 
  84 
  85 def request(query, params):
  86     query = urlencode({'q': query})[2:]
  87 
  88     fp = {'query': query}
  89     if paging and search_url.find('{pageno}') >= 0:
  90         fp['pageno'] = (params['pageno'] - 1) * page_size + first_page_num
  91 
  92     params['url'] = search_url.format(**fp)
  93     params['query'] = query
  94 
  95     return params
  96 
  97 
  98 def response(resp):
  99     results = []
  100     dom = html.fromstring(resp.text)
  101     if results_xpath:
  102         for result in dom.xpath(results_xpath):
  103             url = extract_url(result.xpath(url_xpath), search_url)
  104             title = extract_text(result.xpath(title_xpath)[0])
  105             content = extract_text(result.xpath(content_xpath)[0])
  106             results.append({'url': url, 'title': title, 'content': content})
  107     else:
  108         for url, title, content in zip(
  109             (extract_url(x, search_url) for
  110              x in dom.xpath(url_xpath)),
  111             map(extract_text, dom.xpath(title_xpath)),
  112             map(extract_text, dom.xpath(content_xpath))
  113         ):
  114             results.append({'url': url, 'title': title, 'content': content})
  115 
  116     if not suggestion_xpath:
  117         return results
  118     for suggestion in dom.xpath(suggestion_xpath):
  119         results.append({'suggestion': extract_text(suggestion)})
  120     return results
  121
  [end of searx/engines/xpath.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/searx/engines/xpath.py b/searx/engines/xpath.py
  --- a/searx/engines/xpath.py
  +++ b/searx/engines/xpath.py
  @@ -42,7 +42,9 @@
           return ''.join(xpath_results)
       else:
           # it's a element
  -        return html_to_text(xpath_results.text_content()).strip()
  +        text = html.tostring(xpath_results, encoding='unicode', method='text', with_tail=False)
  +        text = text.strip().replace('\n', ' ')
  +        return ' '.join(text.split())
   
   
   def extract_url(xpath_results, search_url):
  
verification_info: {"golden_diff": "diff --git a/searx/engines/xpath.py b/searx/engines/xpath.py\n--- a/searx/engines/xpath.py\n+++ b/searx/engines/xpath.py\n@@ -42,7 +42,9 @@\n         return ''.join(xpath_results)\n     else:\n         # it's a element\n-        return html_to_text(xpath_results.text_content()).strip()\n+        text = html.tostring(xpath_results, encoding='unicode', method='text', with_tail=False)\n+        text = text.strip().replace('\\n', ' ')\n+        return ' '.join(text.split())\n \n \n def extract_url(xpath_results, search_url):\n", "issue": "Tags <xml> are hidden from result titles\n\n", "before_files": [{"content": "from lxml import html\nfrom urllib import urlencode, unquote\nfrom urlparse import urlparse, urljoin\nfrom lxml.etree import _ElementStringResult, _ElementUnicodeResult\nfrom searx.utils import html_to_text\n\nsearch_url = None\nurl_xpath = None\ncontent_xpath = None\ntitle_xpath = None\nsuggestion_xpath = ''\nresults_xpath = ''\n\n# parameters for engines with paging support\n#\n# number of results on each page\n# (only needed if the site requires not a page number, but an offset)\npage_size = 1\n# number of the first page (usually 0 or 1)\nfirst_page_num = 1\n\n\n'''\nif xpath_results is list, extract the text from each result and concat the list\nif xpath_results is a xml element, extract all the text node from it\n   ( text_content() method from lxml )\nif xpath_results is a string element, then it's already done\n'''\n\n\ndef extract_text(xpath_results):\n    if type(xpath_results) == list:\n        # it's list of result : concat everything using recursive call\n        if not xpath_results:\n            raise Exception('Empty url resultset')\n        result = ''\n        for e in xpath_results:\n            result = result + extract_text(e)\n        return result.strip()\n    elif type(xpath_results) in [_ElementStringResult, _ElementUnicodeResult]:\n        # it's a string\n        return ''.join(xpath_results)\n    else:\n        # it's a element\n        return html_to_text(xpath_results.text_content()).strip()\n\n\ndef extract_url(xpath_results, search_url):\n    url = extract_text(xpath_results)\n\n    if url.startswith('//'):\n        # add http or https to this kind of url //example.com/\n        parsed_search_url = urlparse(search_url)\n        url = parsed_search_url.scheme + url\n    elif url.startswith('/'):\n        # fix relative url to the search engine\n        url = urljoin(search_url, url)\n\n    # normalize url\n    url = normalize_url(url)\n\n    return url\n\n\ndef normalize_url(url):\n    parsed_url = urlparse(url)\n\n    # add a / at this end of the url if there is no path\n    if not parsed_url.netloc:\n        raise Exception('Cannot parse url')\n    if not parsed_url.path:\n        url += '/'\n\n    # FIXME : hack for yahoo\n    if parsed_url.hostname == 'search.yahoo.com'\\\n       and parsed_url.path.startswith('/r'):\n        p = parsed_url.path\n        mark = p.find('/**')\n        if mark != -1:\n            return unquote(p[mark + 3:]).decode('utf-8')\n\n    return url\n\n\ndef request(query, params):\n    query = urlencode({'q': query})[2:]\n\n    fp = {'query': query}\n    if paging and search_url.find('{pageno}') >= 0:\n        fp['pageno'] = (params['pageno'] - 1) * page_size + first_page_num\n\n    params['url'] = search_url.format(**fp)\n    params['query'] = query\n\n    return params\n\n\ndef response(resp):\n    results = []\n    dom = html.fromstring(resp.text)\n    if results_xpath:\n        for result in dom.xpath(results_xpath):\n            url = extract_url(result.xpath(url_xpath), search_url)\n            title = extract_text(result.xpath(title_xpath)[0])\n            content = extract_text(result.xpath(content_xpath)[0])\n            results.append({'url': url, 'title': title, 'content': content})\n    else:\n        for url, title, content in zip(\n            (extract_url(x, search_url) for\n             x in dom.xpath(url_xpath)),\n            map(extract_text, dom.xpath(title_xpath)),\n            map(extract_text, dom.xpath(content_xpath))\n        ):\n            results.append({'url': url, 'title': title, 'content': content})\n\n    if not suggestion_xpath:\n        return results\n    for suggestion in dom.xpath(suggestion_xpath):\n        results.append({'suggestion': extract_text(suggestion)})\n    return results\n", "path": "searx/engines/xpath.py"}]}