We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Tags <xml> are hidden from result titles


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `searx/engines/xpath.py`
Content:
```
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 FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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

{"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"}], "after_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        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\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"}]}