C# 用于检索内部此信息的XPATH表达式<;b></b>&书信电报;br/>;标签

C# 用于检索内部此信息的XPATH表达式<;b></b>&书信电报;br/>;标签,c#,html,.net,vb.net,xpath,C#,Html,.net,Vb.net,Xpath,首先,我对html的了解还不够基本 我有一段html代码: <div class="main_panel_sub"> <p> <p> <b>Genre</b>: pop<br/> <b>Country</b>: USA<br /> <b>

首先,我对html的了解还不够基本

我有一段html代码:

    <div class="main_panel_sub">
        <p>
            <p>
                <b>Genre</b>: pop<br/>
                <b>Country</b>: USA<br />
                <b>Year</b>: 2013<br />
                <b>Audio codec</b>: MP3<br />
                <b>Riptype</b>: tracks<br />
                <b>Bitrate</b>: 320 kbps<br />
                <b>Playtime</b>: 01:06:44<br />
                <b>Size:</b> 153 MB<br />
                <b>Site:</b> 
                <a href='XXXXXXX'>XXXXXXX.com</a>
            </p>
        </p>
在上面的第一行代码中,我得到了字符串
Genre
,而不是Genre值
Pop

第二行是
Year
字符串,而不是
2013

更新:

(有问题的)变体DIV示例:

<div class="main_panel_sub">
<p><p><b>Genre</b>: Synthpop<br />
<b>Year</b>: 2012<br />
<b>Audio codec</b>: MP3<br />
<b>Riptype</b>: tracks<br />
<b>Bitrate</b>: VBR~256 kbps<br />
<b>Playtime</b>: 00:29:21<br />
<b>Size:</b> 57 MB<br />
<b>Site:</b> <a href='http://xxxxxxxxxxxx.com'>xxxx.com</a></p>
</p>

类型:Synthpop
年份:2012年
音频编解码器:MP3
Riptype:轨道
比特率:VBR~256 kbps
播放时间:00:29:21
大小:57MB
地点:

以及我尝试使用的代码:

 Dim fields = (From field In node.SelectNodes("..//div[@class='main_panel_sub']//b")
              Let contentNodes = field.ParentNode.ChildNodes.SkipWhile(Function(e) Not e.Equals(field)).
                                 TakeWhile(Function(e) e.Equals(field) OrElse e.Name <> "b")
                                 Let content = [String].Concat(contentNodes.[Select](Function(e) e.InnerText))
                                 Select content.Split(":")).
                                        ToDictionary(Function(s) s(0).ToLower.Trim(), Function(s) s(1).Trim())
Dim fields=(从节点中的字段选择节点(..//div[@class='main\u panel\u sub']//b”)
让contentNodes=field.ParentNode.ChildNodes.SkipWhile(函数(e)而不是e.Equals(字段))。
TakeWhile(函数(e)e.Equals(字段)或lse e e.Name“b”)
让content=[String].Concat(contentNodes.[Select](函数(e)e.InnerText))
选择content.Split(“:”)。
ToDictionary(函数s(0).ToLower.Trim(),函数s(1.Trim())

解析这样的html是有问题的,因为它列出的属性不一致。所有字段都没有固定的模式。冒号有时位于
b
标记内,并非所有字段都以
br
标记结尾(这将是划分每个字段的一个好方法。如果您对html的格式有任何影响,我会推动为每个字段使用一种一致的格式。或者至少将它们放在无序列表中,或者让选择字段更容易完成

基本上,你会想把所有的字段和它们的内容分组,然后解析出这些组。说起来容易做起来难,但可行

var fields =
    (from field in node.SelectNodes("..//div[@class='main_panel_sub']//b")
    // group the nodes
    let contentNodes = field.ParentNode.ChildNodes
        .SkipWhile(e => e != field)
        .TakeWhile(e => e == field || e.Name != "b")
    // easier to parse as strings
    let content = String.Concat(contentNodes.Select(e => e.InnerText))
    select content.Split(':'))
    .ToDictionary(s => s[0].Trim(), s => s[1].Trim());
var genre = fields["Genre"];
var year = fields["Year"];

是的,不幸的是,html的格式不能很好地坚持纯粹的HAP方法。你必须进行混合才能完成你想要的。Jeff Mercado linq方法不适用于这样的类型:
类型:Synthpop
请你修复它,它以什么方式失败?如果是这样的话重要的是,在问题中,它与您的示例没有太大的不同,因此它应该是有效的。您可以在您的问题(完整的
main_panel_sub
div)中包含它作为一个示例吗?这样我就可以看到需要更改的内容。我已经更新了我的问题,它抛出了一个异常,我认为是因为“b”,我没有使用C#版本,我已将其翻译为VB,但经过任何修改(只是添加了s(0).Tolower)有什么例外?我运行了与您在该代码段上使用的相同的VB代码,对于该示例来说很好。
var fields =
    (from field in node.SelectNodes("..//div[@class='main_panel_sub']//b")
    // group the nodes
    let contentNodes = field.ParentNode.ChildNodes
        .SkipWhile(e => e != field)
        .TakeWhile(e => e == field || e.Name != "b")
    // easier to parse as strings
    let content = String.Concat(contentNodes.Select(e => e.InnerText))
    select content.Split(':'))
    .ToDictionary(s => s[0].Trim(), s => s[1].Trim());
var genre = fields["Genre"];
var year = fields["Year"];