使用HTMLAgilityPack和C#按类名删除元素

8
我将使用html agility pack来读取我的html文档内容并转换为字符串等。完成后,我想通过它们的类删除该内容中的某些元素,但是我遇到了一些问题。
我的Html看起来像这样:
<div id="wrapper">
    <div class="maincolumn" >
        <div class="breadCrumbContainer">
            <div class="breadCrumbs">
            </div>
        </div>

        <div class="seo_list">
            <div class="seo_head">Header</div>
        </div>

Content goes here...
</div>

现在,我使用了xpath选择器来获取所有在 <div> 标签内的内容,并使用 InnerHtml 属性,代码如下:

            node = doc.DocumentNode.SelectSingleNode("//div[@id='wrapper']");
            if (node != null)
            {
                pageContent = node.InnerHtml;
            }

从这个角度来看,我想要删除类名为“breadCrumbContainer”的div。然而,当我使用以下代码时,会出现错误:“在集合中未找到节点“””。
            node = doc.DocumentNode.SelectSingleNode("//div[@id='wrapper']");
            node = node.RemoveChild(node.SelectSingleNode("//div[@class='breadCrumbContainer']"));

            if (node != null)
            {
                pageContent = node.InnerHtml;
            }

请问有人能解释一下吗?我对Xpath不太熟悉,HtmlAgility库更是一窍不通。

谢谢!

Dave


是因为“breadCrumbContainer”节点不是“wrapper”的直接子节点,而.RemoveChild()只能删除直接子节点吗? - mike
我不知道HtmlAgilityPack是否工作方式相同,但在XPath中,"//div"将始终从根节点开始搜索,而不是从当前节点开始。请尝试使用".//div"代替。 - Hans Kesting
好问题,+1。请看我的答案,其中包含完整、非常简短和易于理解的XSLT解决方案。记住:XSLT是专门为此类任务设计的语言,任何其他语言在这些任务上都不如它。 - Dimitre Novatchev
2个回答

13

这是因为RemoveChild只能删除一个直接子元素,而不能删除孙子元素。尝试使用以下方法代替:

    HtmlNode node = doc.DocumentNode.SelectSingleNode("//div[@class='breadCrumbContainer']");
    node.ParentNode.RemoveChild(node);

是的。我太傻了。我本来以为它会将任何子节点都计算为子节点。无论如何,谢谢 :) - Dave

0

这对于XSLT来说是一个超级简单的任务:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
  "div[@class='breadCrumbContainer'
     and
       ancestor::div[@id='wrapper']
      ]
  "/>
</xsl:stylesheet>

当应用此转换到提供的 XML 文档时(添加了另一个 <div> 并包装成 <html> 顶级元素以使其更具挑战性和逼真性):
<html>
 <div id="wrapper">
    <div class="maincolumn" >
        <div class="breadCrumbContainer">
            <div class="breadCrumbs"></div>
        </div>
        <div class="seo_list">
            <div class="seo_head">Header</div>
        </div>  Content goes here...
    </div>
 </div>
 <div>
   Something else here
 </div>
</html>

产生了想要的、正确的结果:

<html>
  <div id="wrapper">
    <div class="maincolumn">
      <div class="seo_list">
        <div class="seo_head">Header</div>
      </div>  Content goes here...
    </div>
  </div>
  <div>
   Something else here
 </div>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接