在每个块内部进行更改

时间:2013-01-09 19:31:59

标签: c# .net html-parsing csquery

我一直在尝试这个奇妙的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 expressions来模拟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());

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

1 个答案:

答案 0 :(得分:4)

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

将DOM元素“包装”为CQ对象(如$(element)的正确方法是使用new而不是Create,例如

CQ cqElement = new CQ(element);

还有一个快捷方式是IDomObject上的方法:

CQ cqElement = element.Cq();

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

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