使用 C# 从 html 中删除自定义 xml 标签

Posted

技术标签:

【中文标题】使用 C# 从 html 中删除自定义 xml 标签【英文标题】:Using C# to remove custom xml tags from html 【发布时间】:2016-01-30 18:47:39 【问题描述】:

我有一个带有一些 html 代码的字符串。但是我需要将该 html 解析为XDocument

string input = String.Concat("<root>", htmlString, "</root>");
var doc = XDocument.Parse(input);

但有时在我的htmlString 中有&lt;o:p&gt;&lt;/o:p&gt; 之类的标签,例如在XDocument.Parse() 中我得到了例外:

':' 字符,十六进制值 0x3A,不能包含在 姓名。第 1 行,位置 650。

如何删除该标签或至少替换标签名称中的':'

在进行解析之前,我尝试删除/替换 ':' 但它不起作用:

try

    Regex regex = new Regex(@"<[:][^>]+>.+?</\[:]>");
    while (regex.IsMatch(htmlString))
    
        htmlString= regex.Replace(htmlString, "");
    

catch  

HTML 示例

<p>Some text</p>

<p class="MsoNormal" style="TEXT-ALIGN: justify; MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: 150%">
    <?xml:namespace prefix="o" ns="urn:schemas-microsoft-com:office:office"?>
    <o:p> </o:p>
</p>

<p>More text</p>

更新

我正在使用HtmlAgilityPack,但它不会删除此标签。

我的代码

ConfigureHtmlDocument();

var htmlDoc = new HtmlDocument();
htmlDoc.OptionFixNestedTags = true;
htmlDoc.LoadHtml(htmlString);

var htmlError = htmlDoc.ParseErrors.SafeAny();

if (!htmlError)
    htmlString= htmlDoc.DocumentNode.InnerHtml;

try

    Regex regex = new Regex(@"<[:][^>]+>.+?</\[:]>");
    while (regex.IsMatch(htmlString))
    
        htmlString= regex.Replace(htmlString, "");
    

catch  

string input = String.Concat("<root>", htmlString, "</root>");
var doc = XDocument.Parse(input);

//more code

ConfigureHtmlDocument()

    if (!HtmlNode.ElementsFlags.ContainsKey("p"))
        HtmlNode.ElementsFlags.Add("p", HtmlElementFlag.Closed);
    else
        HtmlNode.ElementsFlags["p"] = HtmlElementFlag.Closed;

    if (!HtmlNode.ElementsFlags.ContainsKey("ul"))
        HtmlNode.ElementsFlags.Add("ul", HtmlElementFlag.Closed);
    else
        HtmlNode.ElementsFlags["ul"] = HtmlElementFlag.Closed;

    if (!HtmlNode.ElementsFlags.ContainsKey("li"))
        HtmlNode.ElementsFlags.Add("li", HtmlElementFlag.Closed);
    else
        HtmlNode.ElementsFlags["li"] = HtmlElementFlag.Closed;

    if (!HtmlNode.ElementsFlags.ContainsKey("ol"))
        HtmlNode.ElementsFlags.Add("ol", HtmlElementFlag.Closed);
    else
        HtmlNode.ElementsFlags["ol"] = HtmlElementFlag.Closed;

    //more similar code

【问题讨论】:

一般来说,使用 XML 解析器解析一些 HTML 代码并不是一个好主意。 HTML 标记可以包含其他违反“格式良好的 xml”的行为,不仅是您提到的标签,而且从 HTML 的角度来看它仍然有效,但从 XML 的角度来看完全无效。如果您需要解析 HTML - 请考虑使用 Html Agility Pack。 检查this answer。但是,如果 HTML 不是有效的 XHTML,请使用 HtmlAgilityPack 或其替代品。 我正在使用 HtmlAgilityPack 但它不能解决问题。我用该代码更新了我的问题 冒号前的字母是前缀。您必须在 xml/ 中包含每个前缀的命名空间定义 【参考方案1】:

解决了! 正则表达式是错误的。我用这个替换了表达式:

//for remove xml declarations
htmlString = Regex.Replace(texto, @"<\?xml.*\?>", "");

//for remove custom tags like <o:p> and </o:p>
htmlString = Regex.Replace(texto, @"<(?:[\S]\:[\S])[^>]*>", "");
htmlString = Regex.Replace(texto, @"</(?:[\S]\:[\S])[^>]*>", ""); 

现在它可以工作了!

【讨论】:

【参考方案2】:

如果您事先知道命名空间,您可以执行以下简单操作:

htmlString = htmlString.Replace("<o:", "<").Replace("</o:", "</");

【讨论】:

我不能保证标签总是&lt;o:p&gt;。这只是一个例子

以上是关于使用 C# 从 html 中删除自定义 xml 标签的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自定义 XSD 架构编写 XML?

如何使用 C# 从 XML 节点列表中删除节点

如何在 C# 中使用添加的自定义标签将 JSON 转换为 XML

c# 中,如何读取XML文件,并将读取到的内容显示到TreeView中

使用自定义arrayadapter从listview android中删除复选框选择的多个项目

使用 C# 自定义代码从主报告 s-s-rS 调用子报告