4

我一直在尝试奇妙的CsQuery库,它基本上是 jQuery 的 .NET 端口,允许使用 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# lambda 表达式来模拟 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得到了更改),但输出文件没有得到更改。

我认为导致问题的关键在于CQ cqElement = CQ.Create(element);它创建了一个全新的 CsQuery 对象。事实上,如果在第一个 Messagebox 之后我弹出另一个像下面这样的,它不会cqElement

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

关于如何解决这个问题的任何想法?

4

1 回答 1

4

你是绝对正确的:CQ cqElement = CQ.Create(element)是问题所在。这是 CsQuery 和 jQuery 之间最显着区别的核心。使用 jQuery,只有一个 DOM。使用 CsQuery,没有浏览器,因此可以有任意数量的不同 DOM。每次使用Create它都是一个全新的 DOM;而 jQuery 方法/选择器返回一个CQ绑定到同一个 DOM 的新对象。

将 DOM 元素“包装”为CQ对象 的正确方法$(element)是 withnew和 not Create,例如

CQ cqElement = new CQ(element);

还有一个快捷方式是一种方法IDomObject

CQ cqElement = element.Cq();

这些将元素保持在同一个 DOM 中。这些Create方法总是产生一个新的 DOM,当从元素创建时,实际上是克隆它们,因此原始 DOM 不受影响。(元素只能属于一个 DOM;如果您要创建两个不同的 DOM 并使用类似的方法将元素从一个添加到另一个Append,它们将从源中删除。Create自动克隆它们。)。

我相信这可以在文档中更清楚地说明:)

于 2013-01-09T19:45:50.547 回答