【问题标题】:xpath for foreach loopforeach 循环的 xpath
【发布时间】:2017-09-11 20:55:20
【问题描述】:

我有一个用于解析 html 的 foreach 循环,并且我正在使用 xpath。我需要的是关注

<p class="section">sectiontext1</p>
<p class="subsection">subtext1</p> ----need this in first loop
<p class="subsection">subtext2</p>  ---need this in first loop
<p class="section">sectiontext2</p>
<p class="subsection">subtext11</p> ---need this in second loop
<p class="subsection">subtext22</p>  ---- need this in second loop
<p class="section">sectiontext3</p>

foreach (HtmlNode sectionNode in htmldocObject.DocumentNode.SelectNodes("//p[@class='section']"))
        {
            count=count+2;
            string text1 = sectionNode.InnerText;

            foreach (HtmlNode subSectionNode in htmldocObject.DocumentNode.SelectNodes("//p[@class='subsection'][following-sibling::p[@class='section'][1] and preceding-sibling::p[@class='section'][2]]"))
            {
                string text = subSectionNode.InnerText;
            }

        }

我想要做的是循环浏览各个部分并找到特定部分下的每个小节,进行一些处理,然后移动到下一部分以查找该特定部分下的小节。

【问题讨论】:

  • I have a foreach loop to parse html and i am using xpath for it. 请出示该代码。
  • 你为什么要用 xpath 来做这个?您使用的是XSLTXPathNavigator 还是LINQ to XML
  • @mjwills 更新帖子以添加 foreach 循环代码
  • @Matthew Whited - 我在我的 .net c# 应用程序中使用 HTMLAgility 包。我想要做的是网络抓取法规内容并将其转储到 excel 表中。

标签: c# xpath foreach


【解决方案1】:

我无法让 XPath 正常工作,因为您无法引用变量...但您可以使用 LINQ 修复您的查询。

foreach (var section in html.DocumentNode.SelectNodes("//p[@class='section']"))
{
    Console.WriteLine(section.InnerText);
    foreach (var subSection in section?.SelectNodes("following-sibling::p")
                                      ?.TakeWhile(n => n?.Attributes["class"]?.Value != "section")
                                      ?? Enumerable.Empty<HtmlNode>())
        Console.WriteLine("\t" + subSection.InnerText);
}
/*
sectiontext1
        subtext1-1
        subtext1-2
sectiontext2
        subtext2-11
        subtext2-22
sectiontext3
*/

...如果您没有使用 VS2015+ ...

foreach (var subSection in (section.SelectNodes("following-sibling::p") ?? Enumerable.Empty<HtmlNode>())
                                   .TakeWhile(n => n.Attributes["class"].Value != "section"))

... XSLT 中的相同内容 ...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes"/>

  <xsl:template  match="/">
      <xsl:for-each select="//p[@class='section']">
        <xsl:variable name="start" select="." />
        <xsl:value-of select="text()"/><xsl:text>&#10;</xsl:text>
        <xsl:for-each select="following-sibling::p[@class='subsection'][preceding-sibling::p[@class='section'][1]=$start]">
            <xsl:text>&#9;</xsl:text><xsl:value-of select="text()"/><xsl:text>&#10;</xsl:text>
        </xsl:for-each>
      </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

【讨论】:

  • 谢谢。我让它使用以下 xpath - .//p[@class='section-e'][" + count + "]/following-sibling::p[@class='subsection-e' 和 count(preceding -sibling::p[@class='section-e'])=" + count + "] 其中 count 是传递的部分标签数。但我更喜欢你的 linq 版本更简洁明了。
猜你喜欢
  • 2021-05-28
  • 1970-01-01
  • 2016-09-26
  • 2012-07-19
  • 2011-12-03
  • 2020-02-19
  • 2013-10-01
  • 1970-01-01
相关资源
最近更新 更多