【问题标题】:splice html tags in html string在 html 字符串中拼接 html 标签
【发布时间】:2021-06-14 06:37:54
【问题描述】:

我正在使用 htmlagility 包在开始和结束位置删除 <br> 标记,但下面的代码正在从所有位置删除。

HTML 字符串:

 <p><br><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span><br></p>

下面是我删除 br 标签的代码

    using HtmlAgilityPack;

    var document = new HtmlAgilityPack.HtmlDocument();
    document.LoadHtml(input.HTMLString);
    var rootNode = document.DocumentNode;
    var nodes = rootNode.SelectNodes("//br");
    if (nodes != null)
    {
        foreach (var brTag in nodes)
            brTag.Remove();
        this.HTMLString = document.DocumentNode.OuterHtml;
    }

我希望结果字符串看起来像这样

 <p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span></p>

而不是像下面这样在this.HTMLString 中获取字符串

  <p><span>MERV 9 Cartridge<b>&nbsp;</b>Prefilters </span></p>

任何人都可以帮助解决如何仅在字符串的开头和结尾而不是在字符串之间删除br 标记,我正在使用 HTMLAgility 包库

【问题讨论】:

  • 你删除第一个
    ,在你检查第一个标签并搜索结束标签(例如)之后,你检查这个标签的索引,然后用下一个标签来面对标签的索引br>,如果closetag是次要的,那么你删除。
  • 我提到的字符串中不会有结束标签,都是&lt;br&gt;标签本身
  • 您阅读了文档中的所有行还是其中的一行?
  • 首先是所有行,然后识别节点并删除已识别的节点 (br) ,但这里我不想删除 html 字符串之间的标签。我只需要在字符串的开始位置和字符串的结束位置删除标签(br

标签: c# .net string c#-4.0 html-agility-pack


【解决方案1】:

我不确定您的 HTML 是否始终位于 &lt;p&gt; 元素内,或者 &lt;br /&gt; 元素的数量是否因情况而异。如果它没有不同并且您可以依赖外部元素相同,则可以使用它来获取第一个和最后一个 &lt;br/&gt; 元素。

选项 #1 - 当父元素(本例中为 p)已知且 br 元素的数量已知(本例中为 3 个)时。

string html = "<p><br><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span><br></p>";
string outHtml = string.Empty;

var document = new HtmlAgilityPack.HtmlDocument();
document.LoadHtml(html);
var rootNode = document.DocumentNode;
var firstBrNode = rootNode.SelectSingleNode("//p/br[1]");
var lastBrNode = rootNode.SelectSingleNode("//p/br[last()]");

firstBrNode?.Remove();
lastBrNode?.Remove();
outHtml = document.DocumentNode.OuterHtml;

输出:

&lt;p&gt;&lt;span&gt;MERV 9 Cartridge&lt;b&gt;&lt;br&gt;&amp;nbsp;&lt;/b&gt;Prefilters &lt;/span&gt;&lt;/p&gt;


选项#2 - 当父元素未知且br标签的数量未知时,假设如果存在一个br元素,它将保留在HTML中.

string html = "<p><br><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span><br></p>";
// string html = "<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span></p>";
string outHtml = string.Empty;
var document = new HtmlAgilityPack.HtmlDocument();
document.LoadHtml(html);
var rootNode = document.DocumentNode;
// count all br nodes so we can bypass removal of br if there is only one in HTML
var brNodeCount = rootNode.SelectNodes("//br") == null ? 0 : rootNode.SelectNodes("//br").Count;
// get the parent node of the br element to be used in the xpath when we remove
// the br elements this will allow for different parent elements other than the `p` element
var parentNode = rootNode.SelectSingleNode("//br/parent::*");
// only removes br elements if more than one in HTML, assumes if 1 br element is present it's in the middle and will not be removed
if (brNodeCount > 1)
{ 
    var firstBrNode = rootNode.SelectSingleNode($"//{parentNode.Name}/br[1]");
    var lastBrNode = rootNode.SelectSingleNode($"//{parentNode.Name}/br[last()]");
    firstBrNode?.Remove();
    lastBrNode?.Remove();
}
outHtml = document.DocumentNode.OuterHtml;

输出:

&lt;p&gt;&lt;span&gt;MERV 9 Cartridge&lt;b&gt;&lt;br&gt;&amp;nbsp;&lt;/b&gt;Prefilters &lt;/span&gt;&lt;/p&gt;


选项 #3 - 考虑第一个和最后一个文本节点的索引,并删除位于它们“外部”的所有 br 元素。包含空值或全空白值的文本节点将被忽略。

// removes all br tags with an index before the first text node and
// all br tags with an index after the end of the last text node,
// any br tags between are not removed
private string RemoveStartAndEndBrTags(string html)
{
    if (string.IsNullOrEmpty(html)) return html;
    var document = new HtmlAgilityPack.HtmlDocument();
    document.LoadHtml(html);
    var rootNode = document.DocumentNode;
    // get first and last text nodes, excluding any only containing white-space
    var allNonEmptyTextNodes = rootNode.SelectNodes("//text()[not(self::text()[not(normalize-space())])]");
    if (allNonEmptyTextNodes == null || allNonEmptyTextNodes.Count == 0) return html;
    var firstTextNode = allNonEmptyTextNodes[0];
    var lastTextNode = allNonEmptyTextNodes[allNonEmptyTextNodes.Count - 1];
    // get the parent node of the first br element, it will be used when we remove the br elements,
    // this will allow for different parent elements other than the `p` element
    var parentNode = rootNode.SelectSingleNode("//br/parent::*");
    if (parentNode == null) return html;
    var allBrNodes = rootNode.SelectNodes($"//{parentNode.Name}/br");
    foreach (var brNode in allBrNodes)
    {
        if (brNode == null) continue;
        // check index of br nodes against first and last text nodes
        // and remove br nodes that sit outside text nodes
        if (brNode.OuterStartIndex <= firstTextNode.OuterStartIndex
            || brNode.OuterStartIndex >= lastTextNode.OuterStartIndex + lastTextNode.OuterLength)
        { 
            brNode.Remove();
        }
    }
    return document.DocumentNode.OuterHtml;
}

测试 HTML 输入:

<p><br><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span><br></p>
<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span></p>
<p><span>MERV 9 <br>Cartridge<b><br>&nbsp;</b>Prefilters </span></p>
<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters<br> </span></p>
<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters<br></span></p>

测试 HTML 输出:

<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span></p>
<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span></p>
<p><span>MERV 9 <br>Cartridge<b><br>&nbsp;</b>Prefilters </span></p>
<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters </span></p
<p><span>MERV 9 Cartridge<b><br>&nbsp;</b>Prefilters</span></p>

【讨论】:

  • 感谢您的建议,&lt;p&gt; 可能不会在所有情况下都被放置,如果&lt;p&gt; 不存在并且字符串之间只有
    标签,这将起作用
  • 对不起,它不适用于这个字符串&lt;p&gt;&lt;span&gt;MERV 9 Cartridge&lt;b&gt;&lt;br&gt;&amp;nbsp;&lt;/b&gt;Prefilters &lt;/span&gt;&lt;/p&gt;
  • 再次抱歉,我正在寻找字符串中间的br标签的数量,并且只想删除html字符串开头和html末尾的br字符串
  • 选项 #2 应该做你想做的事。它适用于您发布的两个 HTML 示例。
  • 上面的第二个选项也适用于此&lt;p&gt;&lt;span&gt;MERV 9 &lt;br&gt;Cartridge&lt;b&gt;&lt;br&gt;&amp;nbsp;&lt;/b&gt;Prefilters &lt;/span&gt;&lt;/p&gt;,在这种情况下,这实际上应该保留两个标签。 br 计数是两个放在字符串之间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 2014-11-16
  • 2012-01-19
  • 1970-01-01
相关资源
最近更新 更多