0

我想从这个 html-snippet 中提取这两个源属性:

<audio controls>
<source src="horse.mp3" type="audio/mpeg">
<source src="horse.ogg" type="audio/ogg">
<embed height="50" width="100" src="horse.mp3">
</audio>

这是我所做的:

首先,我提取所有音频标签(包括您在上面看到的那个):

var audio_tags = HtmlDoc.DocumentNode.SelectNodes("//" + HTML.TAG_AUDIO); 

之后,我尝试使用这段代码从 HtmlNodeCollection audio_tags 中提取源元素:

foreach (HtmlNode link in audio_tags)
        {
            if (link != null)
            {
                string url;
                string type;
                // select all source tags, see here for an example: http://www.w3schools.com/html/html_sounds.asp
                if(link.HasChildNodes)
                {
                    var children = link.ChildNodes;
                    if (children != null)
                    {
                        foreach (HtmlNode child in children)
                        {
                            Console.WriteLine(children[0].GetAttributeValue("type", "err").ToString() + "||" + children[0].OriginalName);
                            Console.WriteLine(children[1].GetAttributeValue("type", "errrr").ToString() + "||" + children[1].OriginalName);
 ...

写入行表明第一个元素不存在,因为打印了“err”。但它应该是第一个源元素。我会很高兴有一些提示。

编辑:

这些写入的输出是:

 err||#text
 audio/mpeg||source

和nr。儿童元素的数量为 2。

4

1 回答 1

1

第一个问题是您的<source>标签未关闭。AgilityPack 以这样的方式自动关闭它,即第二个<source><embed>标签位于第一个<source>标签内。但 AgilityPack知道<embed>是一个自闭合标签。幸运的是,有一种方法可以说,您希望将标签视为自闭合标签:

HtmlNode.ElementsFlags.Add("source", HtmlElementFlag.Empty);

第二个问题是文本节点。每个换行符/空格序列都被转换为文本节点。我假设你想摆脱它们,所以这些节点可能会被跳过。

最后一个,您可以通过将 LINQ 或 xpath 与 AgilityPack 结合使用来提高代码的可读性。这是一个例子:

doc.LoadHtml(html);
doc.DocumentNode
    .Descendants("audio")
    .SelectMany(a =>
        a.ChildNodes.Where(n => n.GetType() != typeof(HtmlTextNode))
    ).ToList()
    .ForEach(n => 
        Console.WriteLine("{0}||{1}", n.GetAttributeValue("type", "err"), n.OriginalName)
    );

这会让你得到类似的东西:

audio/mpeg||source 
audio/ogg||source 
err||embed
于 2013-02-06T18:40:44.303 回答