删除两个元素之间的所有元素 [英] Delete all elements between two elements

查看:70
本文介绍了删除两个元素之间的所有元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有大约2500个不同标准的html文件.我需要删除其中的页脚部分.下面的HTML代码是我的文件页脚之一,我需要删除两个hr元素以及两者之间的元素.

I have about 2500 html-files of different standards. I need to remove the footer part of them. The HTML-code below is one of my files footer, and I need to remove the two hr-elements and the elements between the two.

到目前为止,我只尝试使用xpath(和HTML Agility Pack)selectSingleNodeDocumentNode.SelectNodes("//hr");定位hr元素.然后尝试使用foreach进行迭代. 但是我对使用XPath正确使用实在是个菜鸟,而且不知道如何选择节点及其兄弟姐妹(?)来删除它们.

So far I have only tried targeting the hr-element with xpath (and HTML Agility Pack) selectSingleNode and DocumentNode.SelectNodes("//hr");. And then try to iterate with a foreach. But I am too much of a noob to use XPath properly, and don't know how to select the node and its siblings(?) to delete them.

这是到目前为止,在这个社区的帮助下. :)

This is what I've got so far, with the help of this community. :)

private static void RemoveHR(IEnumerable<string> files)
{
    var document = new HtmlDocument();
    List<string> hr = new List<string>();
    List<string> errors = new List<string>();
    int i = 0;
    foreach (var file in files)
    {
        try
        {
            document.Load(@file);
            i++;
            var hrs = document.DocumentNode.SelectNodes("//hr");
            foreach (var hr in hrs) hr.Remove();
            document.Save(@file);

        }
        catch (Exception Ex)
        {
            errors.Add(file + "|" + Ex.Message);
        }
    }
    using (StreamWriter logger = File.CreateText(@"D:\websites\dev.openjournal.tld\public\arkivet\ErrorLogs\hr_error_log.txt"))
    {
        foreach (var file in errors)
        {
            logger.WriteLine(file);
        }
    }
    int nrOfHr = hr.Count();
    int nrOfErrors = errors.Count();
    Console.WriteLine("Number of hr elements collected: {0}", nrOfHr);
    Console.WriteLine("Number of files missing hr element: {0}", nrOfErrors);
}

HTML来源:

<hr color=#ff00ff SIZE=3> //start element
<p style="text-align : center; color : Red; font-weight : bold;">How to cite this paper:</i></p>
<p style="text-align : left; color : black;">Ekmek&ccedil;ioglu, F. &Ccedil;una, Lynch, Michael F. &amp; Willett, Peter   (1996)&nbsp; &quot;Stemming and N-gram matching for term conflation in Turkish texts&quot;&nbsp;<em>Information Research</em>, <strong>1</strong>(1) Available at: http://informationr.net/ir/2-2/paper13.html</p>
<p style="text-align : center">&copy; the authors, 1996.</p>
<hr color="#ff00ff" size="1"><div align="center">Check for citations, <a href="http://scholar.google.co.uk/scholar?hl=en&amp;q=http://informationr.net/ir/2-2/paper13.html&amp;btnG=Search&amp;as_sdt=2000">using Google Scholar</a></div>
                                 <hr color="#ff00ff" size="1">
<table border="0" cellpadding="15" cellspacing="0" align="center">
<tr> 
    <td><a href="infres22.html"><h4>Contents</h4></a></td>
    <td align="center" valign="top"><h5 align="center"><IMG SRC="http://counter.digits.net/wc/-d/-z/6/-b/FF0033/paper13" ALIGN=middle  WIDTH=60 HEIGHT=20 BORDER=0 HSPACE=4 VSPACE=2><br><a href="http://www.digits.net/ ">Web Counter</a><br>Counting only since 13 December 2002</h5></td>
    <td><a href="http://InformationR.net/ir/"><h4>Home</h4></a></td>
</tr>
</table>
<hr color=#ff00ff SIZE=3> //end element

编辑 我对目标节点的前同级和后同级进行了一些实验.不幸的是,它没有在列表中包含目标节点.

EDIT I experimented a bit with preceding-sibling and following-sibling to target nodes. Unfortunately it does not include the targeted nodes in the list.

var footerTags = document.DocumentNode.SelectNodes("//*[preceding-sibling::p[contains(text(),'How to cite this')] and following-sibling::hr[@color = '#ff00ff']]");

它找到带有文本"How to cite this"的段落,然后选择它之间的所有节点,直到颜色为"ff00ff"的小时.但是不包括要删除的列表中的实际选定节点,因此需要将它们与选定节点一起删除.

It finds the paragraph with the text "How to cite this", then selects all node between it and down to the hr with color "ff00ff". But does not include the actual selected nodes in list to remove, and they need to be removed along with the selected nodes.

推荐答案

假设开始结束节点 确实相同 (与标签的名称,属性和属性值相同),就像您在上面的注释中提到的那样,这并不难:

Assuming the start and end nodes are truly the same (same tag name, attributes, and attribute values) as you mentioned in the comments above, it's not too hard:

  1. 选择起始节点.
  2. 遍历并删除直到并包括端节点的每个同级.
  3. 删除起始节点.

示例HTML:

var html =
@"<!doctype html system 'html.dtd'>
<html><head></head>
<body>

<div>DO NOT DELETE</div>

<hr color=""#ff00ff"" SIZE='3'> //start element
<p style='text-align : center; color : Red; font-weight : bold;'>How to cite this paper:</i></p>
<p style='text-align : left; color : black;'>Ekmek&ccedil;ioglu, F. &Ccedil;una, Lynch, Michael F. &amp; Willett, Peter   (1996)&nbsp; &quot;Stemming and N-gram matching for term conflation in Turkish texts&quot;&nbsp;<em>Information Research</em>, <strong>1</strong>(1) Available at: http://informationr.net/ir/2-2/paper13.html</p>
<p style='text-align : center'>&copy; the authors, 1996.</p>
<hr color='#ff00ff' size='1'><div align='center'>Check for citations, <a href='http://scholar.google.co.uk/scholar?hl=en&amp;q=http://informationr.net/ir/2-2/paper13.html&amp;btnG=Search&amp;as_sdt=2000'>using Google Scholar</a></div>
                                 <hr color='#ff00ff' size='1'>
<table border='0' cellpadding='15' cellspacing='0' align='center'>
<tr> 
    <td><a href='infres22.html'><h4>Contents</h4></a></td>
    <td align='center' valign='top'><h5 align='center'><IMG SRC='http://counter.digits.net/wc/-d/-z/6/-b/FF0033/paper13' ALIGN=middle  WIDTH=60 HEIGHT=20 BORDER=0 HSPACE=4 VSPACE=2><br><a href='http://www.digits.net/'>Web Counter</a><br>Counting only since 13 December 2002</h5></td>
    <td><a href='http://InformationR.net/ir/'><h4>Home</h4></a></td>
</tr>
</table>
<hr COLOR='#ff00ff' SIZE=""3""> //end element

<div>DO NOT DELETE</div>
</body>
</html>";

解析它:

var document = new HtmlDocument();
document.LoadHtml(html);
var startNode = document.DocumentNode.SelectSingleNode("//hr[@size='3'][@color='#ff00ff']");
// account for mismatched quotes in HTML source
var quotesRegex = new Regex("[\"']");
var startNodeNoQuotes = quotesRegex.Replace(startNode.OuterHtml, "");
HtmlNode siblingNode;

while ( (siblingNode = startNode.NextSibling) != null)
{
    siblingNode.Remove();
    if (quotesRegex.Replace(siblingNode.OuterHtml, "") == startNodeNoQuotes)
    {
        break;  // end node
    }
}

startNode.Remove();

结果输出:

<!doctype html system 'html.dtd'>
<html><head></head>
<body>

<div>DO NOT DELETE</div>

 //end element

<div>DO NOT DELETE</div>
</body>
</html>

这篇关于删除两个元素之间的所有元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆