如何从 CDATA 中删除 href 标记

本文关键字:删除 href 标记 CDATA | 更新日期: 2023-09-27 18:30:36

我在xml文档中有以下CDATA:

<![CDATA[ <p xmlns="">Refer to the below: <br/>
</p>
<table xmlns:abc="http://google.com pic.xsd" cellspacing="1" class="c" type="custom" width="100%">
    <tbody>
        <tr xmlns="">            
            <th style="text-align: left">Basic offers...</th>
        </tr>
        <tr xmlns="">
            <td style="text-align: left">Faster network</td>
            <td style="text-align: left">
            <ul>                
                <li>Session</li>
            </ul>
            </td>
        </tr>
        <tr xmlns="">
            <td style="text-align: left">capabilities</td>
            <td style="text-align: left">
            <ul>                
                <li>Navigation,</li>
                <li>message, and</li>
                <li>contacts</li>
            </ul>
            </td>
        </tr>
        <tr xmlns="">
            <td style="text-align: left">Data</td>
            <td style="text-align: left">
            <p>Here visit google for more info <a href="http://www.google.com" target="_blank"><font color="#0033cc">www.google.com</font></a>.</p>
            <p>Remove this href tag <a href="/abc/def/{T}/t/1" target="_blank">Information</a> remove the tag.</p>
            </td>
        </tr>
    </tbody>
</table>
<p xmlns=""><br/>
</p>
  ]]> 

我想了解一些如何扫描 href="/abc/def 并删除以 abc/def 开头的 href 标签。在上面的示例中,删除 href 标签,只需在标签内保留"信息"文本。CDATA 可以有多个带有"abc/def..."的 href 标签。我正在为此应用程序使用 C#。有人可以帮我并告诉我如何做到这一点吗?我应该使用正则表达式还是有办法使用 xml 本身来做到这一点?

这是我正在尝试的正则表达式:

"<a href='"/abc/def/.*></a>"

我想保留 href 标签的内部文本,只需删除标签即可。但是上面的正则表达式不起作用。

如何从 CDATA 中删除 href 标记

使用 HtmlAgilityPack

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var nodes = doc.DocumentNode
    .Descendants("a")
    .Where(n => n.Attributes.Any(a => a.Name == "href" && a.Value.StartsWith("/abc/def")))
    .ToArray();
foreach(var node in nodes)
{
    node.ParentNode.RemoveChild(node,true);
}
var newHtml = doc.DocumentNode.InnerHtml;

我会使用HtmlAgilityPack来完成这项任务。任务本身非常简单:使用 xpath 选择节点,然后删除它们。剩下的就是得到结果 HTML:

它是一个 .NET 代码库,允许您解析"网络外" HTML 文件。解析器对"现实世界"格式错误非常宽容 .HTML。对象模型与提议的 System.xml 非常相似, 但对于 HTML 文档(或流)。

var doc = new HtmlDocument();
doc.LoadHtml(xml);
var anchors = doc.DocumentNode.SelectNodes("//a[starts-with(@href, '/abc/def')]");
foreach (var anchor in anchors.ToList())
    anchor.Remove();
var result= doc.DocumentNode.OuterHtml;

这将得到你想要的。

编辑:

如果只想删除 href 属性,请将此行anchor.Remove()更改为此行anchor.Attributes["href"].Remove();

如果 HTML 是格式正确的 XML(乍一看,它看起来像),则可以将 cdata 节点的文本加载到新的 XML 文档中,根据需要修改 XML,然后将原始 cdata 节点的文本替换为已修改文档的 XML 文本。

由于 cdata 根据定义不会在原始 XML 文档中解析,因此您需要一个辅助文档。

注意:我不建议在整个XML字符串上运行此正则表达式 - 因为大多数人都认为这很糟糕。在正确遍历期间,以下正则表达式可以并且应该在文档的各个节点上运行。该解决方案作为单个正则表达式替换发布在整个 xmlString 上,因为这是用户请求的,并且他们在使正则表达式语句适应其特定情况时遇到了麻烦 - 我逐个字符编写代码以匹配他们打算尽可能接近使用它的方式。


要去除 url 以 /abc/def/ 开头的所有 href 标签,最好使用正则表达式:

result = Regex.Replace(xmlString, @"<a href='"/abc/def/.*>(.*)</a>", "$1");

以下评论的跟进

根据MSDN:

在指定的输入字符串中,将指定正则表达式匹配的所有字符串替换为指定的替换字符串。

此替换将发生在所有实例上,而不仅仅是第一个实例。如果其余部分不起作用,那是因为它们有一些不同的东西与正则表达式不匹配。

例如,如果在某些情况下 a 和 href 之间有多余的空格,或者在 href 字段之前指定了目标字段,则需要使用不太具体的替换:

result = Regex.Replace(str, @"<a.*href='"/OST/OSTdisplay/.*>(.*)</a>", "$1");