public static IEnumerable <QNode> P_s(this IEnumerable <QNode> nodes, params object[] path) { foreach (var entry in path) { var i = entry as int?; string s = null; if (i == null) { s = entry?.ToString(); if (!s.IsNullOrEmpty() && char.IsDigit(s[0])) { i = ConvertHlp.ToInt(s); } } if (i != null) { nodes = nodes.Select(n => n.Nodes().ElementAtOrDefault(i.Value)).Where(n => n != null); } else if (s == "*") { nodes = nodes.SelectMany(n => n.Nodes()); } else { nodes = nodes.SelectMany(n => n.P(s)); } } return(nodes); }
public static NitroBolt.Wui.HtmlResult <HElement> HView(object _state, JsonData[] jsons, HContext context) { var state = _state.As <MainState>() ?? new MainState(); foreach (var json in jsons.OrEmpty()) { switch (json.JPath("data", "command")?.ToString()) { case "mouse-event": { var x = ConvertHlp.ToInt(json.JPath("data", "x")); var y = ConvertHlp.ToInt(json.JPath("data", "y")); if (x != null && y != null) { using (var client = new MouseClient(Zuma.VmIp)) { client.MoveTo(x.Value, y.Value, 800, 600); } } } break; case "reset": { using (var client = new MouseClient(Zuma.VmIp)) { client.Reset(); } } break; case "screenshot": { new VmClient().Screenshot().Save(context.HttpContext.Server.MapPath($"~/App_Data/{DateTime.UtcNow.Ticks}.png")); } break; default: break; } } var page = Page(state); return(new NitroBolt.Wui.HtmlResult <HElement> { Html = page, State = state, }); }
public async static Task <Post[]> Thread(int threadId) { using var httpClient = new HttpClient(); var html_bytes = await httpClient.GetByteArrayAsync(BaseUrl + $"showflat.php?Number={threadId}"); var html_raw = Ru.GetString(html_bytes); html_raw = html_raw.Replace("this.scrollHeight > 49", ""); var xhtml = NitroBolt.HtmlParsing.HtmlHelper.LoadXElementFromText(html_raw); var htmlBody = xhtml.Element("body"); var bordersTable = htmlBody.Elements("table").ElementAtOrDefault(3)?.Descendants("table") .FirstOrDefault(_table => _table.Attribute("class")?.Value == "tableborders"); var postTable = bordersTable?.Elements("tr").ElementAtOrDefault(1)?.Element("td")?.Element("table"); var postTrs = (postTable?.Elements("tr")?.ToArray()).OrEmpty(); var posts = new List <Post>(); for (var i = 0; i < postTrs.Length; i += 2) { var postHeaderTr = postTrs[i]; var postBodyTr = postTrs[i + 1]; var userTd = postHeaderTr?.Elements("td")?.ElementAtOrDefault(0); var subjectTd = postHeaderTr?.Elements("td")?.ElementAtOrDefault(1); var bodyTd = postBodyTr?.Element("td"); var title = subjectTd?.Element("table")?.Element("tr")?.Element("td")?.Element("b")?.Value?.Trim(); var postIdName = userTd?.Element("a")?.Attribute("name")?.Value; var postId = ConvertHlp.ToInt(postIdName?.StartsWith("Post") == true ? postIdName.Substring("Post".Length) : postIdName); if (postId == null || title?.EmptyAsNull() == null) { continue; } var postBody = bodyTd?.Element("table")?.Element("tr")?.Element("td")?.Element("font"); var bodyHtml = postBody.Nodes().Select(node => node.ToString()).JoinToString(); posts.Add(new Post(postId.Value, title, bodyHtml)); } return(posts.ToArray()); }
static Board TrToBoard(XElement tr) { var(name, title, description) = ParseBoardTitle(tr.Elements("td").ElementAtOrDefault(1)); var threadCount = ConvertHlp.ToInt(tr.Elements("td").ElementAtOrDefault(2)?.Value?.Trim()); var postCount = ConvertHlp.ToInt(tr.Elements("td").ElementAtOrDefault(3)?.Value?.Trim()); var isFlashed = ParseIsFlashed(tr.Elements("td").ElementAtOrDefault(0)); var lastPost = ParseLastPost(tr.Elements("td").ElementAtOrDefault(4)); var moderators = ParseModerators(tr.Elements("td").ElementAtOrDefault(5)); if (name == null) { return(null); } return(new Board(name, title, description, moderators: moderators, state: new BoardState(isFlashed, threadCount, postCount, lastPost))); }
public static int[] GetNewsIdsForTag(IDataLayer fabricConnection, int tagId) { //DataTable table = fabricConnection.GetTable("", // "Select parent_id From light_link Where child_id = @tagId and type_id = @linkType", // new DbParameter("tagId", tagId), // new DbParameter("linkType", TopicType.TagLinks.Kind) //); DataTable table = fabricConnection.GetTable("", "Select obj_id From light_object Where obj_id in (Select parent_id From light_link Where child_id = @tagId and type_id = @linkType) order by act_from desc", new DbParameter("tagId", tagId), new DbParameter("linkType", TopicType.TagLinks.Kind) ); int[] newsIds = new int[table.Rows.Count]; for (int i = 0; i < newsIds.Length; ++i) { newsIds[i] = ConvertHlp.ToInt(table.Rows[i][0]) ?? 0; } return(newsIds); }
public static TResponse Process <TRequest, TResponse, TState>(TRequest request, IRequestAdapter <TRequest, TResponse> requestAdapter, Func <TState, JsonData[], TRequest, HtmlResult <HElement> > page) where TState : class, new() { if (requestAdapter.IsGetMethod(request)) { var result = page(new TState(), Array <JsonData> .Empty, request); var rawResponse = requestAdapter.RawResponse(result); if (rawResponse != null) { return(rawResponse); } var html = result.Html; var head = html.Element("head") ?? new HElement("head"); var startHead = new HElement(head.Name, head.Attributes, Scripts(frame: Guid.NewGuid().ToString(), refreshPeriod: result.RefreshPeriod ?? TimeSpan.FromSeconds(10)), head.Nodes ); var firstHtmlTransformer = result.As <HtmlResult>()?.FirstHtmlTransformer ?? FirstHtmlTransformer; html = firstHtmlTransformer(new HElement("html", startHead, html.Nodes.Where(node => node.As <HElement>()?.Name.LocalName != "head"))); var toHtmlText = result.As <HtmlResult>()?.ToHtmlText ?? ToHtmlText; return(requestAdapter.ToResponse(toHtmlText(html), "text/html", result)); } else { var json = Parse(requestAdapter.Content(request)); var route = requestAdapter.Frame(request) ?? "<null>"; var frame = route + ":" + json.JPath("frame")?.ToString(); var cycle = ConvertHlp.ToInt(json.JPath("cycle")).OrDefault(0); var prev = PopUpdate(frame, cycle); var json_commands = (json.JPath("commands").As <JArray>()?.Select(j => new JsonData(j)).ToArray()).OrEmpty(); HtmlResult <HElement> result = null; var watch = System.Diagnostics.Stopwatch.StartNew(); try { result = page(prev?.Item2?.State.As <TState>() ?? new TState(), json_commands, request); } catch (Exception exc) //HACK ловятся все ошибки для того, чтобы не зациклилась страница. Добавить обработку ошибок на сторону js. { result = new HtmlResult <HElement> { State = prev.Item2.State, Html = prev.Item2.Page }; } watch.Stop(); var rawResponse = requestAdapter.RawResponse(result); if (rawResponse != null) { return(rawResponse); } var isPartial = result.Html.Name.LocalName != "html"; var toBody = isPartial ? html => html : (Func <HElement, HElement>)(html => html?.Element("body")); var js_updates = HtmlJavaScriptDiffer.JsSync(new HElementProvider(), toBody(prev?.Item2?.Page), toBody(result.Html)).ToArray(); var jupdate = new Dictionary <string, object>() { { "cycle", prev.Item1 }, { "prev_cycle", cycle }, { "processed_commands", json_commands.Length }, { "updates", js_updates } }; PushUpdate(frame, prev.Item1, result.Html, result.State, watch.Elapsed); return(requestAdapter.ToResponse(JsonConvert.SerializeObject(jupdate), "application/javascript", result)); } }
public static IHtmlControl GetCenter(HttpContext httpContext, SiteState state, LightObject currentUser, string kind, int?id, out string title, out string description, out SchemaOrg schema, out bool wideContent) { title = ""; description = ""; schema = null; wideContent = false; SiteSettings settings = context.SiteSettings; switch (kind) { case "": { title = store.SEO.Get(SEOType.MainTitle); description = store.SEO.Get(SEOType.MainDescription); LightSection main = store.Sections.FindMenu("main"); return(ViewHlp.GetMainView(state, currentUser)); } case "news": { if (!context.News.ObjectById.Exist(id)) { return(null); } TopicStorage topicStorage = context.NewsStorages.ForTopic(id ?? 0); LightKin topic = topicStorage.Topic; //string tagsDisplay; IHtmlControl view = ViewNewsHlp.GetNewsView(state, currentUser, topicStorage, out description); title = topic.Get(NewsType.Title); //string postfix = ""; //if (!StringHlp.IsEmpty(tagsDisplay)) // postfix = ". "; //description = string.Format("{0}{1}Живое обсуждение баскетбольных событий на basketball.ru.com", // tagsDisplay, postfix //); string logoUrl = settings.FullUrl("/images/logo.gif"); schema = new SchemaOrg("NewsArticle", settings.FullUrl(UrlHlp.ShopUrl("news", id)), title, new string[] { logoUrl }, topic.Get(ObjectType.ActFrom), topic.Get(ObjectType.ActTill), topic.Get(TopicType.OriginName), settings.Organization, logoUrl, description ); return(view); } case "article": { if (!context.Articles.ObjectById.Exist(id)) { return(null); } TopicStorage topicStorage = context.ArticleStorages.ForTopic(id ?? 0); LightKin topic = topicStorage.Topic; title = topic.Get(ArticleType.Title); description = topic.Get(ArticleType.Annotation); string logoUrl = settings.FullUrl("/images/logo.gif"); schema = new SchemaOrg("Article", settings.FullUrl(UrlHlp.ShopUrl("article", id)), title, new string[] { logoUrl }, topic.Get(ObjectType.ActFrom), topic.Get(ObjectType.ActTill), topic.Get(TopicType.OriginName), settings.Organization, logoUrl, description ); wideContent = topic.Get(ArticleType.WideContent); return(ViewArticleHlp.GetArticleView(state, currentUser, topicStorage)); } case "topic": { TopicStorage topic = context.Forum.TopicsStorages.ForTopic(id ?? 0); title = topic.Topic.Get(TopicType.Title); int pageNumber = 0; { string pageArg = httpContext.Get("page"); int messageCount = topic.MessageLink.AllRows.Length; if (pageArg == "last" && messageCount > 0) { pageNumber = BinaryHlp.RoundUp(messageCount, ViewForumHlp.forumMessageCountOnPage) - 1; } else { pageNumber = ConvertHlp.ToInt(pageArg) ?? 0; } } return(ViewForumHlp.GetTopicView(state, currentUser, topic, pageNumber)); } case "tags": { int?tagId = httpContext.GetUInt("tag"); int pageNumber = httpContext.GetUInt("page") ?? 0; return(ViewNewsHlp.GetTagView(state, currentUser, tagId, pageNumber, out title, out description)); } case "search": { return(ViewNewsHlp.GetFoundTagListView(state, out title)); } case "user": { LightObject user = context.UserStorage.FindUser(id ?? -1); if (user == null) { return(null); } title = string.Format("{0} - Basketball.ru.com", user.Get(UserType.Login)); return(ViewUserHlp.GetUserView(state, currentUser, user)); } case "page": { LightSection section = store.Sections.FindSection(id); title = FabricHlp.GetSeoTitle(section, section.Get(SectionType.Title)); description = FabricHlp.GetSeoDescription(section, section.Get(SectionType.Annotation)); int pageNumber = httpContext.GetUInt("page") ?? 0; string designKind = section.Get(SectionType.DesignKind); switch (designKind) { case "news": { int[] allNewsIds = context.News.AllObjectIds; return(ViewNewsHlp.GetNewsListView(state, currentUser, pageNumber)); } case "articles": return(ViewArticleHlp.GetArticleListView(state, currentUser, pageNumber)); case "forum": return(ViewForumHlp.GetForumView(state, currentUser, section)); case "forumSection": return(ViewForumHlp.GetForumSectionView(state, currentUser, section)); default: return(null); } } case "dialog": { if (currentUser == null) { return(null); } if (id == null) { return(ViewDialogueHlp.GetDialogueView(state, context.ForumConnection, context.UserStorage, currentUser, out title )); } LightObject collocutor = context.UserStorage.FindUser(id.Value); if (collocutor == null) { return(null); } return(ViewDialogueHlp.GetCorrespondenceView(state, context.ForumConnection, currentUser, collocutor, out title )); } case "passwordreset": title = "Восстановление пароля - basketball.ru.com"; return(ViewHlp.GetRestorePasswordView(state)); case "register": title = "Регистрация - basketball.ru.com"; return(ViewHlp.GetRegisterView(state)); case "confirmation": { title = "Подтверждение аккаунта"; int? userId = httpContext.GetUInt("id"); string hash = httpContext.Get("hash"); if (userId == null) { return(ViewUserHlp.GetMessageView( "Вам выслано письмо с кодом активации. Чтобы завершить процедуру регистрации, пройдите по ссылке, указанной в письме, и учётная запись будет активирована. Если вы не получили письмо, то попробуйте войти на сайт со своим логином и паролем. Тогда письмо будет отправлено повторно." )); } if (StringHlp.IsEmpty(hash)) { return(null); } LightObject user = context.UserStorage.FindUser(userId.Value); if (userId == null) { return(null); } if (!user.Get(UserType.NotConfirmed)) { return(ViewUserHlp.GetMessageView("Пользователь успешно активирован")); } string login = user.Get(UserType.Login); string etalon = UserHlp.CalcConfirmationCode(user.Id, login, "bbbin"); if (hash?.ToLower() != etalon?.ToLower()) { return(ViewUserHlp.GetMessageView("Неверный хэш")); } LightObject editUser = DataBox.LoadObject(context.UserConnection, UserType.User, user.Id); editUser.Set(UserType.NotConfirmed, false); editUser.Box.Update(); context.UserStorage.Update(); string xmlLogin = UserType.Login.CreateXmlIds("", login); HttpContext.Current.SetUserAndCookie(xmlLogin); state.RedirectUrl = "/"; return(new HPanel()); } } return(null); }
public static HtmlResult <HElement> HView(ConsoleState state, JsonData[] jsons, HttpRequestMessage context) { foreach (var json in jsons.OrEmpty()) { switch (json.JPath("data", "command")?.ToString()) { default: break; } } var watch = new System.Diagnostics.Stopwatch(); watch.Start(); var qs_functions_doc = QParser.Parse(System.IO.File.ReadAllText(HostingEnvironment.MapPath("~/") + "/Data/functions.qs")); var qs_functions = QTransformator.ResolveFunctions(qs_functions_doc.P_s("function")); var qs_function_index = qs_functions.GroupBy(function => function.P_("name", "*").AsString()) .ToDictionary(group => group.Key, group => group.ToArray()); var calculator = new QCalculator(qs_functions); var qs_text = System.IO.File.ReadAllText(HostingEnvironment.MapPath("~/") + "/Data/textbook.math.6.qs"); var qs = QParser.Parse(qs_text); var prepareDuration = watch.Elapsed; watch.Reset(); watch.Start(); var typed_qs = QTransformator.ProcessAll(qs.P_s("point", "*"), qs_function_index); typed_qs = QTransformator.Transform(typed_qs, calculator.Identify).ToArray(); var transformDuration = watch.Elapsed; watch.Reset(); watch.Start(); var results = typed_qs.Select(typedNode => Tuple.Create(typedNode, calculator.Calculate(typedNode))) .ToArray(); var calculateDuration = watch.Elapsed; watch.Reset(); watch.Start(); var notifies = QTransformator.Browse(typed_qs, QTransformator.Error).ToArray(); var types = QTransformator.Browse(typed_qs, q => q.C(0).P("type").OrEmpty().FirstOrDefault().C(0)).ToArray(); var usedFunctions = QTransformator.Browse(typed_qs, q => QTransformator.IsAnyType(q.C(0).P("type").OrEmpty().FirstOrDefault().C(0)) ? null : q) .Where(pair => pair.Item2 != null).ToArray(); watch.Stop(); var version = ConvertHlp.ToInt(qs.P_("version", "*").RawValue()); var resultVersionFilename = HostingEnvironment.MapPath("~/App_Data") + $"/textbook.math.6.({version}).qs"; if (!System.IO.File.Exists(resultVersionFilename)) { System.IO.File.WriteAllText(resultVersionFilename, typed_qs.ToText()); } var elements = new[] { h.Div($"Подготовка: {prepareDuration}"), h.Div($"Преобразование: {transformDuration}"), h.Div($"Вычисление: {calculateDuration}"), h.Div($"Notifies: {watch.Elapsed}"), }; return(new HtmlResult <HElement> { Html = Page(state, typed_qs, notifies, types, usedFunctions, calculator.FunctionIndex.Values.SelectMany(_ => _), results, elements, context), State = state, RefreshPeriod = TimeSpan.FromSeconds(2), }); }
public BasketballContext(string rootPath, EditorSelector sectionEditorSelector, EditorSelector unitEditorSelector, IDataLayer userConnection, IDataLayer fabricConnection, IDataLayer messageConnection, IDataLayer forumConnection) { this.rootPath = rootPath; this.imagesPath = Path.Combine(RootPath, "Images"); this.userConnection = userConnection; this.fabricConnection = fabricConnection; this.messageConnection = messageConnection; this.forumConnection = forumConnection; this.sectionEditorSelector = sectionEditorSelector; this.unitEditorSelector = unitEditorSelector; this.userStorage = new UserStorage(userConnection); this.NewsStorages = new TopicStorageCache(fabricConnection, messageConnection, NewsType.News); this.ArticleStorages = new TopicStorageCache(fabricConnection, messageConnection, ArticleType.Article); this.Forum = new ForumStorageCache(fabricConnection, forumConnection); string settingsPath = Path.Combine(rootPath, "SiteSettings.config"); if (!File.Exists(settingsPath)) { this.siteSettings = new SiteSettings(); } else { this.siteSettings = XmlSerialization.Load <SiteSettings>(settingsPath); } this.pull = new TaskPull( new ThreadLabel[] { Labels.Service }, TimeSpan.FromMinutes(15) ); this.newsCache = new Cache <Tuple <ObjectHeadBox, LightHead[]>, long>( delegate { ObjectHeadBox newsBox = new ObjectHeadBox(fabricConnection, string.Format("{0} order by act_from desc", DataCondition.ForTypes(NewsType.News)) ); int[] allNewsIds = newsBox.AllObjectIds; List <LightHead> actualNews = new List <LightHead>(); for (int i = 0; i < Math.Min(22, allNewsIds.Length); ++i) { int newsId = allNewsIds[i]; actualNews.Add(new LightHead(newsBox, newsId)); } return(_.Tuple(newsBox, actualNews.ToArray())); }, delegate { return(newsChangeTick); } ); this.articlesCache = new Cache <Tuple <ObjectBox, LightObject[]>, long>( delegate { ObjectBox articleBox = new ObjectBox(fabricConnection, string.Format("{0} order by act_from desc", DataCondition.ForTypes(ArticleType.Article)) ); int[] allArticleIds = articleBox.AllObjectIds; ObjectBox actualBox = new ObjectBox(FabricConnection, string.Format("{0} order by act_from desc limit 5", DataCondition.ForTypes(ArticleType.Article)) ); List <LightObject> actualArticles = new List <LightObject>(); foreach (int articleId in actualBox.AllObjectIds) { actualArticles.Add(new LightObject(actualBox, articleId)); } return(_.Tuple(articleBox, actualArticles.ToArray())); }, delegate { return(articleChangeTick); } ); this.lightStoreCache = new Cache <IStore, long>( delegate { LightObject contacts = DataBox.LoadOrCreateObject(fabricConnection, ContactsType.Contacts, ContactsType.Kind.CreateXmlIds, "main"); LightObject seo = DataBox.LoadOrCreateObject(fabricConnection, SEOType.SEO, SEOType.Kind.CreateXmlIds, "main"); SectionStorage sections = SectionStorage.Load(fabricConnection); WidgetStorage widgets = WidgetStorage.Load(fabricConnection, siteSettings.DisableScripts); RedirectStorage redirects = RedirectStorage.Load(fabricConnection); SiteStore store = new SiteStore(sections, null, widgets, redirects, contacts, seo); store.Links.AddLink("register", null); store.Links.AddLink("passwordreset", null); return(store); }, delegate { return(dataChangeTick); } ); this.lastPublicationCommentsCache = new Cache <RowLink[], long>( delegate { DataTable table = messageConnection.GetTable("", "Select Distinct article_id From message order by create_time desc limit 10" ); List <RowLink> lastComments = new List <RowLink>(10); foreach (DataRow row in table.Rows) { int topicId = ConvertHlp.ToInt(row[0]) ?? -1; if (News.ObjectById.Exist(topicId)) { TopicStorage topic = NewsStorages.ForTopic(topicId); RowLink lastMessage = _.Last(topic.MessageLink.AllRows); if (lastMessage != null) { lastComments.Add(lastMessage); } } else if (Articles.ObjectById.Exist(topicId)) { TopicStorage topic = ArticleStorages.ForTopic(topicId); RowLink lastMessage = _.Last(topic.MessageLink.AllRows); if (lastMessage != null) { lastComments.Add(lastMessage); } } } return(lastComments.ToArray()); }, delegate { return(publicationCommentChangeTick); } ); this.lastForumCommentsCache = new Cache <RowLink[], long>( delegate { DataTable table = forumConnection.GetTable("", "Select Distinct article_id From message order by create_time desc limit 7" ); List <RowLink> lastComments = new List <RowLink>(7); foreach (DataRow row in table.Rows) { int topicId = ConvertHlp.ToInt(row[0]) ?? -1; TopicStorage topic = Forum.TopicsStorages.ForTopic(topicId); RowLink lastMessage = _.Last(topic.MessageLink.AllRows); if (lastMessage != null) { lastComments.Add(lastMessage); } } return(lastComments.ToArray()); }, delegate { return(forumCommentChangeTick); } ); this.tagsCache = new Cache <TagStore, long>( delegate { ObjectHeadBox tagBox = new ObjectHeadBox(fabricConnection, DataCondition.ForTypes(TagType.Tag) + " order by xml_ids asc"); return(new TagStore(tagBox)); }, delegate { return(tagChangeTick); } ); //this.tagsCache = new Cache<Tuple<ObjectHeadBox, Dictionary<string, int>>, long>( // delegate // { // ObjectHeadBox tagBox = new ObjectHeadBox(fabricConnection, DataCondition.ForTypes(TagType.Tag) + " order by xml_ids asc"); // Dictionary<string, int> tagIdByKey = new Dictionary<string, int>(); // foreach (int tagId in tagBox.AllObjectIds) // { // string tagName = TagType.DisplayName.Get(tagBox, tagId); // if (StringHlp.IsEmpty(tagName)) // continue; // string tagKey = tagName.ToLower(); // tagIdByKey[tagKey] = tagId; // } // return _.Tuple(tagBox, tagIdByKey); // }, // delegate { return tagChangeTick; } //); this.unreadDialogCache = new Cache <TableLink, long>( delegate { return(DialogueHlp.LoadUnreadLink(forumConnection)); }, delegate { return(unreadChangeTick); } ); Pull.StartTask(Labels.Service, SiteTasks.SitemapXmlChecker(this, rootPath, delegate(LinkInfo[] sectionlinks) { List <LightLink> allLinks = new List <LightLink>(); allLinks.AddRange( ArrayHlp.Convert(sectionlinks, delegate(LinkInfo link) { return(new LightLink(link.Directory, null)); }) ); foreach (int articleId in Articles.AllObjectIds) { LightHead article = new LightHead(Articles, articleId); allLinks.Add( new LightLink(UrlHlp.ShopUrl("article", articleId), article.Get(ObjectType.ActTill) ?? article.Get(ObjectType.ActFrom) ) ); } foreach (int newsId in News.AllObjectIds) { LightHead news = new LightHead(News, newsId); allLinks.Add( new LightLink(UrlHlp.ShopUrl("news", newsId), news.Get(ObjectType.ActTill) ?? news.Get(ObjectType.ActFrom) ) ); } //foreach (int tagId in Tags.AllObjectIds) //{ // LightHead tag = new LightHead(Tags, tagId); // allLinks.Add( // new LightLink(string.Format("/tags?tag={0}", tagId) // ) // ); //} return(allLinks.ToArray()); } ) ); }
public static int?ToInt(string s) { return(ConvertHlp.ToInt(s)); }
public static IEnumerable <QNode> W_s(this IEnumerable <QNode> nodes, IEnumerable <object> path, QNode v) { if (path == null || !path.Any()) { return(To_s(v)); } var entry = path.FirstOrDefault(); var qentry = entry as QNode; var i = entry as int?; string s = null; var isAddIfNeed = false; var isOnlySingle = false; if (qentry != null) { s = qentry.AsString(); isAddIfNeed = qentry.Nodes().Any(n => n.AsString() == "+"); isOnlySingle = qentry.Nodes().Any(n => n.AsString() == "!" || n.AsString() == "single"); } else if (i == null) { s = entry?.ToString(); if (!s.IsNullOrEmpty() && char.IsDigit(s[0])) { i = ConvertHlp.ToInt(s); } } if (i != null) { return(nodes.Select(n => q.Q(n.RawValue(), n.Nodes().Skip(i.Value).Concat(W_s(To_s(n.Nodes().ElementAtOrDefault(i.Value)), path.Skip(1), v)).Concat(n.Nodes().Skip(i.Value + 1))))); } else if (s == "*") { return(nodes.Select(n => q.Q(n.RawValue(), W_s(To_s(n), path.Skip(1), v)))); } else { return(nodes.Select(n => { var childs = new List <QNode>(); var isUpdated = false; foreach (var node in n.Nodes()) { if (node.AsString() == s) { if (!isOnlySingle || !isUpdated) { childs.AddRange(W_s(To_s(node), path.Skip(1), v)); } isUpdated = true; } else { childs.Add(node); } } if (isAddIfNeed && !isUpdated) { childs.AddRange(W_s(q.Qs(s), path.Skip(1), v)); } return q.Q(n.RawValue(), childs); } )); } }