/// <summary> /// 生成HTML /// </summary> /// <param name="isTag">是否包含当前标签</param> /// <returns>HTML</returns> public string Html(bool isTag) { if (TagName != null) { if (web.html.NonanalyticTagNames.Contains(TagName)) { if (isTag && TagName.Length != 1) { using (charStream strings = new charStream()) { tagHtml(strings); strings.Write(nodeText.Html); tagRound(strings); return strings.ToString(); } } } else { using (charStream strings = new charStream()) { if (isTag) tagHtml(strings); if (children.count() != 0) { htmlNode node; list<nodeIndex> values = new list<nodeIndex>(); nodeIndex index = new nodeIndex { Values = children }; while (true) { if (index.Values == null) { if (values.Count == 0) break; { index = values.Pop(); index.Values[index.Index].tagRound(strings); if (++index.Index == index.Values.Count) { index.Values = null; continue; } } } node = index.Values[index.Index]; string nodeTagName = node.TagName; bool isNonanalyticTagNames = nodeTagName != null && web.html.NonanalyticTagNames.Contains(nodeTagName); if (node.children.count() == 0 || nodeTagName == null || isNonanalyticTagNames) { if (nodeTagName != null && nodeTagName.Length != 1) node.tagHtml(strings); strings.Write(node.nodeText.Html); if (nodeTagName != null && nodeTagName.Length != 1) node.tagRound(strings); if (++index.Index == index.Values.Count) index.Values = null; } else { node.tagHtml(strings); values.Add(index); index.Values = node.children; index.Index = 0; } } } if (isTag) tagRound(strings); return strings.ToString(); } } } return nodeText.Html; }
/// <summary> /// 子孙节点筛选 /// </summary> /// <param name="path">筛选器</param> /// <param name="value">筛选节点集合</param> /// <returns>匹配的HTML节点集合</returns> private static keyValue<list<htmlNode>, bool> filterNode(filter path, keyValue<list<htmlNode>, bool> value) { list<nodeIndex> values = new list<nodeIndex>(); nodeIndex index = new nodeIndex { Values = value.Key.getList() }; if (index.Values.Count != 0) { if (value.Value) { HashSet<htmlNode> newValues = new HashSet<htmlNode>(), historyNodes = new HashSet<htmlNode>(); if (path.values == null) { if (path.value != null) { string tagName = path.value; while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } htmlNode node = index.Values[index.Index]; if (node.TagName == tagName) newValues.Add(node); if (node.children.count() == 0 || historyNodes.Contains(node)) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); historyNodes.Add(node); index.Values = node.children; index.Index = 0; } } } else { while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } htmlNode node = index.Values[index.Index]; newValues.Add(node); if (node.children.count() == 0 || historyNodes.Contains(node)) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); historyNodes.Add(node); index.Values = node.children; index.Index = 0; } } } } else { staticHashSet<string> tagNames = path.values; while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } htmlNode node = index.Values[index.Index]; if (tagNames.Contains(node.TagName)) newValues.Add(node); if (node.children.count() == 0 || historyNodes.Contains(node)) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); historyNodes.Add(node); index.Values = node.children; index.Index = 0; } } } if (newValues.Count != 0) { return new keyValue<list<htmlNode>, bool>(new list<htmlNode>(newValues), newValues.Count > 1); } } else { list<htmlNode> newValues = new list<htmlNode>(); if (path.values == null) { if (path.value != null) { string tagName = path.value; while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } htmlNode node = index.Values[index.Index]; if (node.TagName == tagName) newValues.Add(node); if (node.children.count() == 0) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); index.Values = node.children; index.Index = 0; } } } else { while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } htmlNode node = index.Values[index.Index]; newValues.Add(node); if (node.children.count() == 0) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); index.Values = node.children; index.Index = 0; } } } } else { staticHashSet<string> tagNames = path.values; while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } htmlNode node = index.Values[index.Index]; if (tagNames.Contains(node.TagName)) newValues.Add(node); if (node.children.count() == 0) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); index.Values = node.children; index.Index = 0; } } } if (newValues.Count != 0) { return new keyValue<list<htmlNode>, bool>(newValues, newValues.Count > 1); } } } return new keyValue<list<htmlNode>, bool>(null, false); }
/// <summary> /// 删除匹配的子孙节点 /// </summary> /// <param name="isRemove">删除节点匹配器</param> public void Remove(func<htmlNode, bool> isRemove) { if (isRemove != null) { removeChilds(isRemove); if (children.count() != 0) { htmlNode node; list<nodeIndex> values = new list<nodeIndex>(); nodeIndex index = new nodeIndex { Values = children }; while (true) { if (index.Values == null) { if (values.Count == 0) break; else index = values.Pop(); } node = index.Values[index.Index]; if (node.children != null) node.removeChilds(isRemove); if (node.children.count() == 0) { if (++index.Index == index.Values.Count) index.Values = null; } else { if (++index.Index != index.Values.Count) values.Add(index); index.Values = node.children; index.Index = 0; } } } } }