C# XPath/HtmlAgilityPack:如何查找属性(href)具有特定值的元素(a)并查找相邻的表列?

C# XPath/HtmlAgilityPack:如何查找属性(href)具有特定值的元素(a)并查找相邻的表列?,c#,html,visual-studio,xpath,html-agility-pack,C#,Html,Visual Studio,Xpath,Html Agility Pack,我非常绝望,因为我不知道如何实现我在问题中所说的。我已经读过无数类似的例子,但没有找到一个在确切情况下有效的。假设我有以下代码: <table><tr> <td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td> <td>&l

我非常绝望,因为我不知道如何实现我在问题中所说的。我已经读过无数类似的例子,但没有找到一个在确切情况下有效的。假设我有以下代码:

<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>
嗯,这显然是错误的,所以如果有人能在这里帮助我,我将非常高兴。另外,如果有人能给我指一些网站,上面用类似这样的例子详细解释了XPath和符号/语法,我将不胜感激。书籍也很受欢迎

PS:我知道我完全可以在不使用XPath的情况下通过正则表达式或C#中的一个简单StreamReader来实现我的目标,并检查每一行是否包含我需要的内容,但a)它对于我的需要来说太脆弱了,因为代码可能会突然换行;b)我真的希望在这方面所做的任何事情都完全遵循XPath项目


提前感谢您的帮助

您的HTML严重损坏,带有不匹配的结束标记
td
。请把它们修好。这只是一幅丑陋的图画

尽管如此,希望Html Agility Pack能够处理您扔给它的任何垃圾,下面介绍如何继续并解析您的垃圾,并在给定
href
的情况下找到
id
img
值:

class Program
{
    static void Main()
    {
        var doc = new HtmlDocument();
        doc.Load("test.html");
        var anchor = doc.DocumentNode.SelectSingleNode("//a[contains(@href, 'url-a')]");
        if (anchor != null)
        {
            var id = anchor.ParentNode.SelectSingleNode("following-sibling::td/a");
            if (id != null)
            {
                Console.WriteLine(id.InnerHtml);
                var img = id.ParentNode.SelectSingleNode("following-sibling::td/a");
                if (img != null)
                {
                    Console.WriteLine(img.InnerHtml);
                }
            }
        }
    }
}

使用以下XPath表达式

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()
<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>
id A
   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()
img A
id A
img A
根据提供的(格式错误但已更正)XML文档进行评估时

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()
<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>
id A
   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()
img A
id A
img A
类似地,此XPath表达式

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()
<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>
id A
   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()
img A
id A
img A
在对同一XML文档(如上)进行评估时,选择另一个需要的文本节点

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()
<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>
id A
   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()
img A
id A
img A
基于XSLT的验证

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()
<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>
id A
   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[2]
                     /a/text()
img A
id A
img A
当此转换应用于XML文档时(如上所述):


好问题,+1。有关选择所需文本节点的确切XPath表达式,请参见我的答案。@_DarinDimitrov:可以使用单个XPath表达式选择所需文本节点(无论承载XPath的编程语言是什么)——请参见我的答案。@Dimitre Novatchev,哇,你是一位真正的XPath大师:-),这真是太棒了。对我来说,它看起来像中文,但如果它能工作,那就真的很好了。@u Darin Dimitrov:是的,它能工作,正如附带的基于XSLT的验证所示。虽然XPath非常精巧和强大,但并不特别困难。您可能对我多年前编写的XPath可视化工具感兴趣。它帮助成千上万的程序员以一种有趣的方式学习XPath——只需使用不同的XPath表达式并逐步改进结果。链接:@Dimitre Novatchev,虽然它看起来很有趣,但XPath并不是我日常代码中使用的东西。我宁愿避免使用它,因为我对它一无所知:-)这么说,我真的很佩服XPath大师,就像我佩服Regex大师一样。我从来没有真正理解过这些观念。我对它们只有基本的了解,需要时我更喜欢使用一些成熟的解析器来完成这项工作,避免编写和维护包含它们的代码。顺便说一句,我刚刚测试了您的XPath表达式,它们可以工作。别客气,我也会试试你的解决方案,并汇报结果。谢谢。好的,我需要做一些调整(例如,因为我只有一部分url,而没有完整的匹配),但总的来说,它就像一个魅力!谢谢。它不仅帮助我解决了这个问题,而且我最终理解了XPath语法在实践中的实际工作原理。我还将查看您的XPath可视化工具,我想这正是我所需要的:-)