Вносить изменения внутри каждого блока

Я пробовал фантастическую библиотеку CsQuery , которая в основном представляет собой порт .NET для jQuery, позволяющий использовать os CSS селекторов и большинства функций jQuery.

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

Следующий фрагмент C# показывает, что я делаю, с эквивалентным кодом JavaScript/jQuery в комментариях.

FileStream doc = File.Open(/*some html file*/);    

CQ dom = CQ.Create(doc);       //$dom = $(document);
CQ images = dom.Select("img"); //$images = $('img');
images.Attr("src","#");        //$images.attr('src','#');

dom.Save(/*Output path*/);//No jQuery equivalent, this just saves the file.

Это работает отлично : если я проверяю выходной файл, все значения src изображения теперь # .

Во всяком случае, если я использую блок Each (который, кажется, работает красиво, используя C# лямбда-выражения для имитации передачи функции javascript) изменения не будут применяться к выходному файлу:

FileStream doc = File.Open(/*same html file*/);

CQ dom = CQ.Create(doc);                 //$dom = $(document);
CQ images = dom.Select("img");           //$images = $('img');
images.Each( (element) => {              //$images.each( function(){
  CQ cqElement = CQ.Create(element);     //  $element = $(this);
  cqElement.Attr("src","#");             //  $element.attr('src','#');
  Messagebox.Show(cqElement.Attr("src"));//  alert($element.attr('src'));
});                                      //});

dom.Save(/*Output path*/);//No jQuery equivalent, this just saves the file.

Несмотря на то, что Messabox показывает «#» для каждого изображения в моей DOM (что означает, что cqElement получает это изменение), выходной файл не получает изменений.

I think the key line causing the problem is CQ cqElement = CQ.Create(element); since it creates a brand new CsQuery object. In fact, if just after the first Messagebox I pop up another one like the following one, it will not have the changes made to the cqElement

Messagebox.Show(dom.Html());//alert($dom.html());

Любая идея о том, как я могу решить эту проблему?

4
nl ja de

2 ответы

Вы абсолютно правы: CQ cqElement = CQ.Create (element) - проблема. Это лежит в основе наиболее сильной разницы между CsQuery и jQuery. С jQuery существует только один DOM. С CsQuery нет браузера, поэтому может быть любое количество различных DOM. Каждый раз, когда вы используете Create , это новый DOM; тогда как методы/селекторы jQuery возвращают новый объект CQ , привязанный к той же DOM.

Правильный способ «обернуть» элемент DOM в качестве объекта CQ , такого как $ (element) , с new , а не Create , например

CQ cqElement = new CQ(element);

Также есть ярлык, который является методом на IDomObject :

CQ cqElement = element.Cq();

Они сохраняют элемент в той же DOM. Методы Create всегда создают новую DOM, а при создании из элементов - фактически clones , поэтому исходная DOM не затрагивается. (Элементы могут принадлежать только одному DOM, если вы должны создать два разных DOM и добавить элементы из одного в другое с помощью метода типа Append , они будут удалены из исходного кода. Create автоматически клонирует их.).

Я уверен, что это можно было бы сделать более ясным в документации :)

4
добавлено
Я чувствую себя ужасно в отношении состояния документов - если бы не тот факт, что это более или менее следует API jQuery, я бы сказал, что это чудо, которое кто-то его использует :) Csq неверен , Я изменил его на Cq давным-давно, чтобы соответствовать имени основного объекта, похоже, что я просто не обновлял документы. У меня есть задатки на веб-сайте, и большая часть API документирована через комментарии xml, я просто не успел закончить его и получить его в Интернете!
добавлено автор Jamie Treworgy, источник
Я вижу, что вы на самом деле очень хороший читатель. Документы полностью ошибочны и говорят, что вы используете Create! Фиксация сейчас.
добавлено автор Jamie Treworgy, источник
То, что я ДЕЙСТВИТЕЛЬНО хотел, было статическим методом по умолчанию, который не существует в C#, поэтому вы можете сказать var cqElement = CQ (element) . В свое время у меня был неявный конструктор, чтобы вы могли сказать CQ cqElement = element . (Теперь вы можете сделать это с помощью строки html, например CQ dom = "<div> ... </div>" ) Похоже, я удалил элемент для элемента, не уверен, почему, придется оглянуться назад. Возможно, меня беспокоила двусмысленность того типа, который мы обсуждаем здесь.
добавлено автор Jamie Treworgy, источник
Это в конечном счете правильно и отлично работает. Не мог бы ожидать меньше от самого создателя CsQuery (congrats! Это действительно awesome работа, о которой я думаю, должен быть намного более известен). Что касается вашего решения, я не мог найти упоминания метода .Cq() в документе. (Я читал о .Csq() , но, похоже, это просто псевдоним точно так же, как и я.)
добавлено автор Sam, источник
Ну, документы могут быть устаревшими, но, по крайней мере, библиотека работает хорошо и кажется очень интуитивным для кого-то, знакомого с jQuery. Во всяком случае, я думаю, что было бы намного больше jQuery-like иметь CQ.csQuery (element); в качестве альтернативы element.Cq() , поскольку он вызывает в очень знакомый способ типичного jQuery (element)
добавлено автор Sam, источник
Я не знаю, можно ли считать это плохой практикой, но решение, которое я бы сделал для этого, создало бы открытый метод S с различными переопределениями, похожими на jQuery $ ( а также оказывается первой буквой слова «Селектор», добавляющей больше мнемоников). Конечно, это будет работать только тогда, когда вам нужно работать только с одним DOM за раз. Я имею в виду что-то вроде этого: pastebin.com/FDzzDBy6
добавлено автор Sam, источник

Вы абсолютно правы: CQ cqElement = CQ.Create (element) - проблема. Это лежит в основе наиболее сильной разницы между CsQuery и jQuery. С jQuery существует только один DOM. С CsQuery нет браузера, поэтому может быть любое количество различных DOM. Каждый раз, когда вы используете Create , это новый DOM; тогда как методы/селекторы jQuery возвращают новый объект CQ , привязанный к той же DOM.

Правильный способ «обернуть» элемент DOM в качестве объекта CQ , такого как $ (element) , с new , а не Create , например

CQ cqElement = new CQ(element);

Также есть ярлык, который является методом на IDomObject :

CQ cqElement = element.Cq();

Они сохраняют элемент в той же DOM. Методы Create всегда создают новую DOM, а при создании из элементов - фактически clones , поэтому исходная DOM не затрагивается. (Элементы могут принадлежать только одному DOM, если вы должны создать два разных DOM и добавить элементы из одного в другое с помощью метода типа Append , они будут удалены из исходного кода. Create автоматически клонирует их.).

Я уверен, что это можно было бы сделать более ясным в документации :)

4
добавлено
Я чувствую себя ужасно в отношении состояния документов - если бы не тот факт, что это более или менее следует API jQuery, я бы сказал, что это чудо, которое кто-то его использует :) Csq неверен , Я изменил его на Cq давным-давно, чтобы соответствовать имени основного объекта, похоже, что я просто не обновлял документы. У меня есть задатки на веб-сайте, и большая часть API документирована через комментарии xml, я просто не успел закончить его и получить его в Интернете!
добавлено автор Jamie Treworgy, источник
Я вижу, что вы на самом деле очень хороший читатель. Документы полностью ошибочны и говорят, что вы используете Create! Фиксация сейчас.
добавлено автор Jamie Treworgy, источник
То, что я ДЕЙСТВИТЕЛЬНО хотел, было статическим методом по умолчанию, который не существует в C#, поэтому вы можете сказать var cqElement = CQ (element) . В свое время у меня был неявный конструктор, чтобы вы могли сказать CQ cqElement = element . (Теперь вы можете сделать это с помощью строки html, например CQ dom = "<div> ... </div>" ) Похоже, я удалил элемент для элемента, не уверен, почему, придется оглянуться назад. Возможно, меня беспокоила двусмысленность того типа, который мы обсуждаем здесь.
добавлено автор Jamie Treworgy, источник
Это в конечном счете правильно и отлично работает. Не мог бы ожидать меньше от самого создателя CsQuery (congrats! Это действительно awesome работа, о которой я думаю, должен быть намного более известен). Что касается вашего решения, я не мог найти упоминания метода .Cq() в документе. (Я читал о .Csq() , но, похоже, это просто псевдоним точно так же, как и я.)
добавлено автор Sam, источник
Ну, документы могут быть устаревшими, но, по крайней мере, библиотека работает хорошо и кажется очень интуитивным для кого-то, знакомого с jQuery. Во всяком случае, я думаю, что было бы намного больше jQuery-like иметь CQ.csQuery (element); в качестве альтернативы element.Cq() , поскольку он вызывает в очень знакомый способ типичного jQuery (element)
добавлено автор Sam, источник
Я не знаю, можно ли считать это плохой практикой, но решение, которое я бы сделал для этого, создало бы открытый метод S с различными переопределениями, похожими на jQuery $ ( а также оказывается первой буквой слова «Селектор», добавляющей больше мнемоников). Конечно, это будет работать только тогда, когда вам нужно работать только с одним DOM за раз. Я имею в виду что-то вроде этого: pastebin.com/FDzzDBy6
добавлено автор Sam, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot