【问题标题】:How to replace the an html tag with another string using c#?如何使用 c# 将 html 标签替换为另一个字符串?
【发布时间】:2016-05-31 05:38:48
【问题描述】:

我有一个 c# 代码,它将读取一个 html 文件并将其内容作为字符串/文本返回。

我需要做的一件事是解析html字符串,查找所有<embed>标签,获取“src”属性中的值,然后用找到的文件内容替换整个<embed>标签在src 标签中。

我正在尝试使用 HtmlAgilityPack 来解析 html 代码。

我唯一不能做的就是如何将<embed>标签替换为另一个字符串,最后将没有<embed>标签的新字符串返回给用户。

这是我所做的

    protected string ParseContent(string content)
    {
        if (content != null)
        {
            //Create a new document parser object
            HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();

            //load the content
            document.LoadHtml(content);

            //Get all embed tags
            IEnumerable<HtmlNode> embedNodes = document.DocumentNode.Descendants("embed");

            //Make sure the content contains at least one <embed> tag
            if (embedNodes.Count() > 0)
            {
                // Outputs the href for external links
                foreach (HtmlNode embedNode in embedNodes)
                {
                    //Mak sure there is a source
                    if (embedNode.Attributes.Contains("src"))
                    {
                        //If the file ends with ".html"
                        if (embedNode.Attributes["src"].Value.EndsWith(".html"))
                        {
                            var newContent = GetContent(embedNode.Attributes["src"].Value);

                            //Here I need to be able to replace the entireembedNode with the newContent
                        }

                    }
                }
            }

            return content;
        }

        return null;
    }

    protected string GetContent(string path)
    {

        if (System.IO.File.Exists(path))
        {
            //The file exists, read its content
            return System.IO.File.ReadAllText(path);
        }

        return null;
    }

如何将&lt;embed&gt; 标记替换为字符串?

【问题讨论】:

    标签: c# asp.net asp.net-mvc-4 asp.net-mvc-5 html-agility-pack


    【解决方案1】:

    我认为您可以尝试获取当前节点的父节点 &lt;embed&gt; 然后替换父节点的子节点 &lt;embed&gt;

    var newContent = GetContent(embedNode.Attributes["src"].Value);
    var ParentNodeT =embedNode.ParentNode;
    var newNodeTtext = "<p>"+newContent+"</p>";
    var newNodeT = HtmlNode.CreateNode(newNodeStr);
    ParentNodeT.ReplaceChild(newNodeT, embedNode);
    

    【讨论】:

    • 我认为从文档中删除节点的问题。如果您查看我的最后一次更新,您会看到发生错误是因为我从列表中删除了一个元素,而不是从 HtmlAgilityPack 文档中删除。我需要找到删除节点的方法。
    • 我以为你要求更换
    • 是的,我正在尝试替换。我想我会通过添加一个 div 作为占位符来做到这一点,然后在读取它的 src 值后删除嵌入标签。但是,我删除了 embedNode.Remove(); 行,但由于某种原因,我的循环仍然出错
    • 如果你使用列表而不是使用枚举会怎样
    • 好吧,可枚举有点像一个虚拟对象,基本上它在内存中不是静态的,在运行循环时,您替换了集合的内容,该内容在另一次迭代中引起了问题,但将其列为静态,因此它不会改变几乎在每次迭代中
    【解决方案2】:

    我想通了。 感谢@COlD TOLD,他建议我将 enumerable 转换为列表

    这是我所做的。

        protected string ParseContent(string content)
        {
            if (content != null)
            {
                //Create a new document parser object
                HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument();
    
                //load the content
                document.LoadHtml(content);
    
                //Get all embed tags
                List<HtmlNode> embedNodes = document.DocumentNode.Descendants("embed").ToList();
    
                //Make sure the content contains at least one <embed> tag
                if (embedNodes.Count() > 0)
                {
                    // Outputs the href for external links
                    foreach (HtmlNode embedNode in embedNodes)
                    {
                        //Mak sure there is a source
                        if (embedNode.Attributes.Contains("src"))
                        {
    
                            if (embedNode.Attributes["src"].Value.EndsWith(".html"))
                            {
                                //At this point we know that the source of the embed tag is set and it is an html file
    
    
                                //Get the full path
                                string embedPath = customBase + embedNode.Attributes["src"].Value;
    
                                //Get the 
                                string newContent = GetContent(embedPath);
    
                                if (newContent != null)
                                {
                                    //Create place holder div node
                                    HtmlNode newNode = document.CreateElement("div");
    
                                    //At this point we know the file exists, load it's content
                                    newNode.InnerHtml = HtmlDocument.HtmlEncode(newContent);
    
                                    //Here I need to be able to replace the entireembedNode with the newContent
                                    document.DocumentNode.InsertAfter(newNode, embedNode);
    
                                    //Remove the code after converting it
                                    embedNode.Remove();
                                }
                            }
    
                        }
                    }
    
                    return document.DocumentNode.OuterHtml;
                }
    
                return content;
            }
    
            return null;
        }
    

    【讨论】:

    • 我可以知道什么是 customBase 吗? @迈克
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2022-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    相关资源
    最近更新 更多