使用HAP删除子节点

时间:2012-05-10 00:16:06

标签: windows-phone-7 html-agility-pack

当我试图从我的xpath中删除一个子节点时,我遇到了一个奇怪的错误: -

System.ArgumentOutOfRangeException未处理   消息=在集合中找不到节点“”

我知道HAP childremoving存在问题,但是如果他们已经使用新版本修复了它,那就是idk。我的问题是我的代码错了还是HAP?无论哪种方式,有没有办法绕过那个并删除那些childnode?

这是我的代码: -

        List<MediNetScheme> medinetScheme = new List<MediNetScheme>();
        HtmlDocument htdoc = new HtmlDocument();
        htdoc.LoadHtml(results);
        foreach (HtmlNode table in htdoc.DocumentNode.SelectNodes("//table[@class='list-medium']/tbody[1]/tr[@class]"))
        {
            string itemValue = string.Empty;
            HtmlNode ansvarig =table.SelectSingleNode("//table[@class='list-medium']/tbody[1]/tr[@class]/td[4]");
            table.RemoveChild(ansvarig, true);
            itemValue = table.InnerText;
            medinetScheme.Add(new MediNetScheme(){Datum=itemValue.Remove(15),Sections=itemValue.Remove(0,15)});
        }
        MediNetScheme.ItemsSource = medinetScheme;

编辑: -

我的HTML文档有一个包含多个具有此xpath的行的表: - “// table [@ class ='list-medium'] / tbody 1 / tr [@class]”。该表中的每一行有5列td 1 ... td [5]。在我的第一个foreach循环中,我使用selectnodes来获取表中每行的HTMLcode。我想要做的是只获得每行中前3个td的innertext,这意味着我需要从每一行中删除td [4]和td [5]。当我使用你编辑的代码时,我能够摆脱第一行中的td [4]和td [5],而不是第一行之后的其他行。

这是我的HTML图片: - enter image description here

2 个答案:

答案 0 :(得分:1)

HtmlAgilityPack中删除父节点的更好方法是:

nodeToRemove.ParentNode.RemoveChild(nodeToRemove);

在您的代码中,您可以像这样使用:

List<MediNetScheme> medinetScheme = new List<MediNetScheme>();
HtmlDocument htdoc = new HtmlDocument();
htdoc.LoadHtml(results);
foreach (HtmlNode table in htdoc.DocumentNode.SelectNodes("//table[@class='list-medium']/tbody[1]/tr[@class]"))
{
    string itemValue = string.Empty;
    HtmlNode ansvarig =table.SelectSingleNode("//table[@class='list-medium']/tbody[1]/tr[@class]/td[4]");
    ansvarig.ParentNode.RemoveChild(ansvarig);
    itemValue = table.InnerText;
    medinetScheme.Add(new MediNetScheme(){Datum=itemValue.Remove(15),Sections=itemValue.Remove(0,15)});
 }
 MediNetScheme.ItemsSource = medinetScheme;

我希望这对你有用:)

EDITED: 你想在每一行中得到三个第一个td的InnerText。 我正在检查你的代码,我认为foreach中的xpath是错误的。

我会用linq更改经典计数循环的xpath:

foreach (HtmlNode trNodes in htdoc.DocumentNode.SelectNodes("//table[@class='list-medium']/tbody[1]/tr[@class]"))
{
    string itemValue = string.Empty;
    int position = 1;
    foreach (var td in tr.DescendantNodes("td"))
    {
        itemValue = td .InnerText;
        medinetScheme.Add(new MediNetScheme(){Datum=itemValue.Remove(15),Sections=itemValue.Remove(0,15)});
        position++;
        if (position == 3)
            break;
    }

答案 1 :(得分:0)

经过几个小时的测试不同的代码和方法来实现我想要的东西,我想出来了。

但我要感谢vfportero的答案并将其标记为答案。

我的问题的编辑版本的答案就是这段代码;)

List<MediNetScheme> medinetScheme = new List<MediNetScheme>();
        HtmlDocument htdoc = new HtmlDocument();
        htdoc.LoadHtml(results);
        foreach (HtmlNode table in htdoc.DocumentNode.SelectNodes("//table[@class='list-medium']/tbody[1]/tr[@class]"))
        {
            table.ChildNodes.RemoveAt(3);
            string itemValue = table.InnerText;
            medinetScheme.Add(new MediNetScheme(){Datum=itemValue.Remove(15),Sections=itemValue.Remove(0,15)}); 
        }
        MediNetScheme.ItemsSource = medinetScheme;

你可以看到我省略了RemoveChild方法因为它没有做我想要的事情(plz阅读我的问题的编辑),而是我使用.ChildNodes.RemoveAt(int //你要删除的孩子的地方) 。 希望这将有助于其他一些人面临同样的问题。

此致