代码之家  ›  专栏  ›  技术社区  ›  Christer Johansson

使用XPath查找所有JavaScript类型脚本元素

  •  2
  • Christer Johansson  · 技术社区  · 7 年前

    我想找到所有 <script> 使用HTML agility pack(加上LINQ和XPath)在一系列HTML文档中添加元素。 这些文档的页眉中有脚本元素,页脚中有谷歌分析。首先,我尝试以头脚本为目标并删除它们。我的记事本++显示我有719个脚本元素,但我的控制台应用程序只找到其中的55个。

    我需要som帮助来正确定位它们,以便从文档中删除它们。

    源文件(头部结构),

    <!doctype html system "html.dtd">
    <html>
    <head>
    <link rel="stylesheet" href="../IRstyle.css" type="text/css">
    <title>Non-hierarchic document clustering</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="keywords" content="">
    <meta name="VW96.objecttype" content="Document">
    
    <script language="JavaScript" type="text/JavaScript">
    //Javascript-code goes here
    </script>
    </head>
    <body>    
    <!--Body contents goes here-->
    
    <!-- in footer -->
    <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
    </script>
    <script type="text/javascript">
    _uacct = "UA-67XXXX-X";
    urchinTracker();
    </script>
    </body>
    </html>
    

    到目前为止,我已经尝试使用JavaScript来定位“语言”类型,但在解析html/head时只得到了一些点击。我的方法从列表中获取文件名。现在,该方法打印出列表中收集的脚本数,这将更改为“脚本”。删除();'一旦我找到正确的搜索字符串。

    private static void FindTagsToRemove(IEnumerable<string> files)
    {
        var doc = new HtmlDocument();
        List<string> scripts = new List<string>();
        List<string> errors = new List<string>();
        try
        {
            foreach (var file in files)
            {
                doc.Load(@file);
                var head = doc.DocumentNode.SelectSingleNode("html/head");
                var nodes = new List<HtmlNode>();
                bool isScript = false;
    
                foreach (var node in head.ChildNodes.ToList())
                {
                    if (node.NodeType == HtmlNodeType.Element && node.Name.Contains("script"))
                    {
                        isScript = !isScript;
                        scripts.Add(node.OuterHtml);
                        Console.WriteLine(node.OuterHtml);
                    }
                    else if (isScript)
                    {
                        nodes.Add(node);
                        node.Remove();
                    }
                }
            }
            int nr_scripts = scripts.Count();
            Console.WriteLine("Number of scripts in collection: {0}", nr_scripts);
        }
        catch (Exception Ex)
        {
            Console.WriteLine(Ex.Message);
        }
    }
    

    如果有人有更好的方法来定位head节点中的JavaScripts,我们将不胜感激。感谢您的帮助!:)

    1 回复  |  直到 7 年前
        1
  •  2
  •   kuujinbo    7 年前

    如果你只需要 <script> 元素节点,使用 descendant-or-self ( // ) . 示例HTML:

    var html =
    @"<!doctype html system 'html.dtd'>
    <html>
    <head>
    <link rel='stylesheet' href='../IRstyle.css' type='text/css'>
    <title>Non-hierarchic document clustering</title>
    <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
    <meta name='keywords' content=''>
    <meta name='VW96.objecttype' content='Document'>
    <script language='JavaScript' type='text/JavaScript'>
    //Javascript-code goes here
    </script>
    </head>
    <body>    
    <!--Body contents goes here-->
    
    <!-- in footer -->
    <script src='http://www.google-analytics.com/urchin.js' type='text/javascript'>
    </script>
    <script type='text/javascript'>
    _uacct = 'UA-67XXXX-X';
    urchinTracker();
    </script>
    </body>
    </html>";
    

    分析示例:

    var document = new HtmlDocument();
    document.LoadHtml(html);
    // target only <script> in <head>
    // var scriptTags = document.DocumentNode.SelectNodes("//head/script");
    var scriptTags = document.DocumentNode.SelectNodes("//script");
    
    foreach (var script in scriptTags) script.Remove();    
    
    document.Save(OUTPUT);
    

    输出:

    <!doctype html system 'html.dtd'>
    <html>
    <head>
    <link rel='stylesheet' href='../IRstyle.css' type='text/css'>
    <title>Non-hierarchic document clustering</title>
    <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
    <meta name='keywords' content=''>
    <meta name='VW96.objecttype' content='Document'>
    
    </head>
    <body>    
    <!--Body contents goes here-->
    
    <!-- in footer -->
    
    
    </body>
    </html>