繁体   English   中英

如何从C#System.Windows.Form.HtmlElement中提取*立即*文本(即不是子代中的文本)

[英]How do I extract the *immediate* text from a C# System.Windows.Form.HtmlElement (i.e. NOT the text in children)

在C#中,如何获取不包含其子级文本的System.Windows.Form.HtmlElement的文本?

如果我有

<div>aaa<div>bbb<div>ccc</div><div>ddd</div></div></div>

那么整个内容的InnerText属性是“ aaabbbcccddd”,而我只想要“ aaa”。

我认为这应该是微不足道的,但是我还没有发现任何东西可以在C#中产生HtmlElement的“立即”文本。 更多可笑的想法是从父母那里“减去”孩子们的InnerText,但这对于我确定是微不足道的事情来说是一笔疯狂的工作。

(我想要的只是访问HtmlElement的Text节点。)

我一定会感谢任何人都可以提供的任何帮助(或指针)。

非常感谢。

例子:

<div>aaa<div>bbb<div>ccc</div><div>ddd</div></div></div>  -> Produce "aaa"
<div><div>ccc</div><div>ddd</div></div>                   -> Produce ""
<div>ccc</div>                                            -> Produce "ccc" 

编辑

有很多方法可以使这只猫变皮,但没有一种优雅。 但是,考虑到我的限制(不是我的HTML,很可能是无效的),我认为Aleksey Bykov的解决方案与我所需要的解决方案最接近(实际上,我的确实现了他在上一条评论中建议的解决方案。)

我选择了他的解决方案,并投票赞成所有其他我认为可行的解决方案,但对我而言并不是最佳选择。 我将再次检查以支持其他似乎可行的解决方案。

非常感谢。

也许比这更简单,如果您愿意使用XmlDocument而不是HtmlDocument-您可以只使用XmlElement的'Value'属性。

这段代码为您提到的3种情况提供了所需的输出:

class Program
{
    private static string[] htmlTests = {@"<div>aaa<div>bbb<div>ccc</div><div>ddd</div></div></div>",
                                         @"<div><div>ccc</div><div>ddd</div></div>",
                                         @"<div>ccc</div>" };
    static void Main(string[] args)
    {
        var page = new XmlDocument();

        foreach (var test in htmlTests)
        {
            page.LoadXml(test);
            Console.WriteLine(page.DocumentElement.FirstChild.Value);
        }
    }
}

输出:

aaa

ccc

我不确定HtmlElement是什么意思,但是使用XmlElement可以做到:

using System;
using System.Xml;
using System.Linq;
using System.Collections.Generic;
using System.Text;

public static class XmlUtils {

    public static IEnumerable<String> GetImmediateTextValues(XmlNode node) {
        var values = node.ChildNodes.Cast<XmlNode>().Aggregate(
            new List<String>(),
            (xs, x) => { if (x.NodeType == XmlNodeType.Text) { xs.Add(x.Value); } return xs; }
        );
        return values;
    }

    public static String GetImmediateJoinedTextValues(XmlNode node, String delimiter) {
        var values = GetImmediateTextValues(node);
        var text = String.Join(delimiter, values.ToArray());
        return text;
    }
}

编辑:

好吧,如果你的HtmlElement来自System.Windows.Forms的,那么你需要做的是使用它的一个DOMElement财产试图将其转换为中定义的COM接口之一MSHTML 因此,您所需要做的就是能够确定您正在查看的元素是否为文本节点并获得其值。 首先,您必须添加对mshtml COM库的引用。 您可以执行以下操作(我无法立即验证此代码)。

public Bool IsTextNode(HtmlElement element) {
  var result = false;
  var nativeNode = element.DomElement as mshtml.IHTMLDOMNode;
  if (nativeNode != null) {
      var nodeType = nativeNode.nodeType;
      result = nodeType == 3; // -- TextNode: http://msdn.microsoft.com/en-us/library/aa704085(v=vs.85).aspx
  }
  return result

}

好吧,您可以执行以下操作(假设您的输入位于名为“ input”的字符串中):

string pattern = @">.*?<";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase); 

MatchCollection matches = rgx.Matches(input);
var first_match = matches[0].ToString();
string result = first_match.Substring(1, first_match.Length - 2);

我可能不会这样做(或者只是继续匹配第一个<div></div>的字符串)...在这里,为了获得额外的荣誉:

int start = pattern.IndexOf(">") + 1;
int end = pattern.IndexOf("<", start);
string result = input.Substring(start, end - start);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM