我想从这个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||#text
audio/mpeg||source
并且nr。儿童的元素是2。
答案 0 :(得分: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