Ejemplo n.º 1
0
        /// <summary>
        /// Will call the GSA using the specified Query object. All parameters of the query object will be used to construct the call.
        /// </summary>
        /// <param name="query">The <see cref="Query"/> object that encapsulates the query parameters </param>
        /// <param name="cookie">The optional authentication cookie to send with the request</param>
        /// <returns>The <see cref="ISearchResult"/></returns>
        public ISearchResult Search(IQuery query, HttpCookie cookie = null)
        {
            XDocument document;

            try
            {
                var url = query.ConstructQuery();

                if (query.Access == SearchAccess.Secure || query.Access == SearchAccess.All)
                {
                    //Secure search, we need to jump through some hoops

                    var cookieCollection = new CookieCollection();

                    //Do we have an authentication cookie to send with the request?
                    if (cookie != null)
                    {

                        var requestCookie = new Cookie(cookie.Name, cookie.Value, "/", query.GetDomain());
                        requestCookie.Expires = cookie.Expires;
                        requestCookie.HttpOnly = cookie.HttpOnly;
                        requestCookie.Secure = cookie.Secure;

                        cookieCollection.Add(requestCookie);
                    }

                    var xml = CallUrl(url, null, cookieCollection);

                    document = XDocument.Parse(xml);
                }
                else
                {
                    document = XDocument.Load(url);
                }
            }
            catch (Exception ex)
            {
                return new SearchResult { Error = "Server error occured while loading XML" };
            }

            if (document.Root == null)
            {
                return new SearchResult { Error = "The XML appears Malformed. No Root element found." };

            }

            var result = new SearchResult();

            var tm = document.Root.Element("TM");
            if (tm != null)
            {
                result.ExecutionTime = tm.Value;
            }
            var rq = document.Root.Element("Q");
            if (rq != null)
            {
                result.Query = rq.Value;
            }

            result.Version = document.Root.Attribute("VER").Value;

            result.Parameters = new List<ResultParameter>();

            foreach (var param in document.Root.Elements("PARAM"))
            {
                var resultParameter = new ResultParameter();
                resultParameter.Name = param.Attribute("name").Value;
                resultParameter.Value = param.Attribute("value").Value;
                resultParameter.OriginalValue = param.Attribute("original_value").Value;
                result.Parameters.Add(resultParameter);
            }

            result.SearchHits = new List<SearchHit>();

            var res = document.Root.Element("RES");
            if (res != null)
            {
                //The search gave results
                var matches = res.Element("M");
                if (matches != null)
                {
                    result.NumberOfHits = int.Parse(matches.Value);
                }

                var filter = res.Element("FI");
                if (filter != null)
                {
                    result.Filtering = filter.Value;
                }

                var nb = res.Element("NB");
                if (nb != null)
                {
                    var nexturl = nb.Element("NU");
                    if (nexturl != null)
                    {
                        result.NextUrl = nexturl.Value;
                    }

                    var prevurl = nb.Element("NP");
                    if (prevurl != null)
                    {
                        result.PreviousUrl = prevurl.Value;
                    }
                }

                foreach (var hit in res.Elements("R"))
                {
                    var searchHit = new SearchHit();
                    searchHit.Index = int.Parse(hit.Attribute("N").Value);

                    var url = hit.Element("U");
                    if (url != null)
                    {
                        searchHit.Url = url.Value;
                    }

                    var encodedUrl = hit.Element("UE");
                    if (encodedUrl != null)
                    {
                        searchHit.EncodedUrl = encodedUrl.Value;
                    }

                    var title = hit.Element("T");
                    if (title != null)
                    {
                        searchHit.Title = title.Value;
                    }

                    var rating = hit.Element("RK");
                    if (rating != null)
                    {
                        searchHit.Rating = int.Parse(rating.Value);
                    }

                    var snippet = hit.Element("S");
                    if (snippet != null)
                    {
                        searchHit.Snippet = snippet.Value;
                    }

                    var mimeType = hit.Attribute("MIME");
                    if (mimeType != null)
                    {
                        searchHit.MimeType = mimeType.Value;
                    }

                    var has = hit.Element("HAS");
                    if (has != null)
                    {
                        var c = has.Element("C");
                        if (c != null)
                        {
                            var sz = c.Attribute("SZ");
                            if (sz != null)
                            {
                                searchHit.Size = sz.Value;
                            }
                        }
                    }
                    searchHit.MetaTags = new Dictionary<string, string>();

                    foreach (var mt in hit.Elements("MT"))
                    {
                        var n = mt.Attribute("N");
                        if (n != null)
                        {
                            var v = mt.Attribute("V");
                            if (v != null)
                            {
                                searchHit.MetaTags.Add(n.Value, v.Value);
                            }
                        }
                    }

                    result.SearchHits.Add(searchHit);
                }

                result.Facets = new List<Facet>();

                var facets = res.Element("PARM");
                if (facets != null)
                {
                    //We have facets or "dynamic navigation" as it's called in google reference
                    foreach (var pmt in facets.Elements("PMT"))
                    {
                        var facet = new Facet();

                        var nm = pmt.Attribute("NM");
                        if (nm != null)
                        {
                            facet.MetaName = nm.Value;
                        }

                        var dn = pmt.Attribute("DN");
                        if (dn != null)
                        {
                            facet.DisplayName = dn.Value;
                        }

                        var ir = pmt.Attribute("IR");
                        if (ir != null)
                        {
                            facet.IsRange = int.Parse(ir.Value) > 0;
                        }

                        var t = pmt.Attribute("T");
                        if (t != null)
                        {
                            facet.FacetType = (FacetType)int.Parse(t.Value);
                        }

                        facet.FacetItems = new List<FacetItem>();

                        foreach (var pv in pmt.Elements("PV"))
                        {
                            var facetItem = new FacetItem();

                            var v = pv.Attribute("V");
                            if (v != null)
                            {
                                facetItem.Value = v.Value;
                            }

                            var l = pv.Attribute("L");
                            if (l != null)
                            {
                                facetItem.LowRange = l.Value;
                            }

                            var h = pv.Attribute("H");
                            if (h != null)
                            {
                                facetItem.HighRange = h.Value;
                            }

                            var c = pv.Attribute("C");
                            if (c != null)
                            {
                                facetItem.Count = int.Parse(c.Value);
                            }
                            facetItem.MetaName = facet.MetaName;

                            facet.FacetItems.Add(facetItem);
                        }

                        result.Facets.Add(facet);
                    }
                }

            }

            result.KeyMatches = new List<KeyMatch>();

            //We have keyMatches
            foreach (var gm in document.Root.Elements("GM"))
            {
                var keyMatch = new KeyMatch();

                var gl = gm.Element("GL");
                if (gl != null)
                {
                    keyMatch.Url = gl.Value;
                }

                var gd = gm.Element("GD");
                if (gd != null)
                {
                    keyMatch.Description = gd.Value;
                }
                result.KeyMatches.Add(keyMatch);
            }

            result.SpellingSuggestions = new List<string>();

            var spellings = document.Root.Element("Spelling");
            if (spellings != null)
            {
                //We have spelling suggestions
                foreach (var suggestion in spellings.Elements("Suggestion"))
                {
                    var q = suggestion.Attribute("q");
                    if (q != null)
                    {
                        result.SpellingSuggestions.Add(q.Value);
                    }
                }
            }

            result.Synonyms = new List<string>();

            var synonyms = document.Root.Element("Synonyms");
            if (synonyms != null)
            {
                //We have synonyms to the submitted query
                foreach (var synonym in synonyms.Elements("OneSynonym"))
                {
                    var q = synonym.Attribute("q");
                    if (q != null)
                    {
                        result.Synonyms.Add(q.Value);
                    }
                }
            }

            return result;
        }