HtmlAgilityPack заменить узел

c# html-agility-pack

Вопрос

Я хочу заменить узел новым узлом. Как я могу получить точную позицию узла и выполнить полную замену?

Я пробовал следующее, но я не могу понять, как получить индекс узла или родительский узел для вызова ReplaceChild() .

string html = "<b>bold_one</b><strong>strong</strong><b>bold_two</b>";
HtmlDocument document = new HtmlDocument();
document.LoadHtml(html);

var bolds = document.DocumentNode.Descendants().Where(item => item.Name == "b");

foreach (var item in bolds)
{

    string newNodeHtml = GenerateNewNodeHtml();
    HtmlNode newNode = new HtmlNode(HtmlNodeType.Text, document, ?);
    item.ParentNode.ReplaceChild( )
}

Принятый ответ

Чтобы создать новый узел, используйте метод фабрики HtmlNode.CreateNode() , не используйте конструктор напрямую.

Этот код должен сработать для вас:

var htmlStr = "<b>bold_one</b><strong>strong</strong><b>bold_two</b>";
var doc = new HtmlDocument();
doc.LoadHtml(htmlStr);

var query = doc.DocumentNode.Descendants("b");
foreach (var item in query.ToList())
{
    var newNodeStr = "<foo>bar</foo>";
    var newNode = HtmlNode.CreateNode(newNodeStr);
    item.ParentNode.ReplaceChild(newNode, item);
}

Обратите внимание, что нам нужно вызвать ToList() в запросе, мы будем модифицировать документ, чтобы он не сработал, если мы этого не сделаем.


Если вы хотите заменить эту строку:

"some text <b>node</b> <strong>another node</strong>"

Проблема в том, что это уже не один узел, а серия узлов. Вы можете разбирать его с помощью HtmlNode.CreateNode() но в конце вы ссылаетесь только на первый узел последовательности. Вам нужно будет заменить его с помощью родительского узла.

var htmlStr = "<b>bold_one</b><strong>strong</strong><b>bold_two</b>";
var doc = new HtmlDocument();
doc.LoadHtml(htmlStr);

var query = doc.DocumentNode.Descendants("b");
foreach (var item in query.ToList())
{
    var newNodesStr = "some text <b>node</b> <strong>another node</strong>";
    var newHeadNode = HtmlNode.CreateNode(newNodesStr);
    item.ParentNode.ReplaceChild(newHeadNode.ParentNode, item);
}

Популярные ответы

Я использую HtmlDocument.DocumentNode для вновь созданного узла.

string html = "<b>bold_one</b><strong>strong</strong><b>bold_two</b>";
HtmlDocument document = new HtmlDocument();
document.LoadHtml(html);
var bolds = document.DocumentNode.Descendants().Where(item => item.Name == "b");
foreach (var item in bolds)
{
    string newNodeHtml = GenerateNewNodeHtml();
    var nodeDocument = new HtmlDocument();
    nodeDocument.LoadHtml(newNodeHtml);
    item.ParentNode.ReplaceChild(nodeDocument.DocumentNode);
}


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему