如何通过简单快速的比较检查DomDocument是否已更改? [英] How to check if a DomDocument was changed with a simple and fast comparison?

查看:48
本文介绍了如何通过简单快速的比较检查DomDocument是否已更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在进行某些操作之前和之后,我只需要比较相同的 DomDocument 对象,即快速检查。如果操作更改了对象...,我需要一些可以在以下上下文中使用的 serialize_DomDocument()存在类似的东西吗?):

I need only to compare the same DomDocument object before and after some operation, a "fast check" if the operation changed the object... I need some serialize_DomDocument() (exists something like?) that can be used in the following context:


  1. $ obj DomDocumemt 对象(对象的状态是所有属性和所有documentElement内容的值)。

  1. $obj is a DomDocumemt object (the "state of the object" is the value of all properties and all documentElement contents).

$ dump = serialize_DomDocument($ obj) 怎么做?? / strong>如何转储对象的状态? ...不是通过 saveXML()方法将所有内容转换为XML,而是(FASTER!)处理所有二进制表示形式(由 $指向的对象) obj )到 $ dump

$dump = serialize_DomDocument($obj)   How to do it?? How to dump the state of the object?   ... Not translating all to XML by saveXML() method, but only (FASTER!) coping all binary representarion (of the object pointed by $obj) to $dump.

执行一些操作(例如,删除节点或更改属性或不执行任何操作)

perform some operation (ex. remove a node or change an attribute or "do nothing")

if($ dump != serialize_DomDocument($ obj))或类似的东西,检查 $ obj 是否已更改。快速比较。 该操作是不执行任何操作还是做某事?

if ($dump != serialize_DomDocument($obj)) or something like it, checking if $obj changed. Fast comparison. The operation was "do nothing" or "do something"?


替代解决方案...


不是理想的方法,但是可以解决某些情况...有些操作(例如,只有 appendChild 或只有 removeChild 的位置,更改始终会影响节点数,因此,对于这种操作,检查节点总数总长度,足够。

Alternative solution...

Not the ideal, but solve some cases... There are some operations (ex. only appendChild's or only removeChild's) where the change always affect the number of nodes, so, for that kind of operations, to check total number of nodes or total length, is enough.

如何比 saveXML()检查得更快?

How to check faster than saveXML()?

注释-1 这篇文章,您无法序列化DomDocument对象。

NOTE-1: as remembered by this post, you can not serialize a DomDocument Object.

NOTE-2 :不是比较两个不同的DOM对象的问题,但更容易,因为无需更改ID等,无需规范表示(!),仅可访问内部代表

NOTE-2: is not a problem of comparing two distinct DOM objects, but something more easy, because not change IDs, etc. not need canonical representation (!), only access to internal representation.

此问题并不是关于控制方式如何变化或更改标志 ,请仔细阅读问题。

This question is not about "how controll changes or a change-flag", please read with attention the question.

此问题不是对理论评论的要求

也许解决方案是关于低级的...我不明白二进制表示是否正确。是转储或使用其他名称,请参见:

Perhaps the solution is about "low level"... I not understand if the "binary representation" is the "dump" or have another name, see:

推荐答案

此处为第二类;解决方案,希望一流

Here a "second class" solution, hoping "first class" here.

...在没有直接解决方案的情况下,有 替代解决方案,正如我在问题的文字...这就是我今天在应用程序中所做的事情:

... in the absence of a direct solution, there are "Alternative solutions", as I expressed in the question's text... And it is waht I am doing today in my application:

,带有XPath count(// node()),我们可以检查是否更改,比 saveXML() 要快,但是如果DOM具有相同数量的节点(例如更改属性值),我们需要通过 saveXML 进行检查,花费内存和/或CPU时间来生成和比较XML。

with a XPath count(//node()) we can check if changed, faster than saveXML(), but if the DOM have same number of nodes (ex. change attribute values), we need to check by saveXML, spending memory and/or CPU time to generate and to compare XMLs.

// $old_dom is the original document, 
$old_xp = new DOMXpath($old_dom);
// ... holding $old_n (and perhaps $old_xml) in a cache 
$old_n = $old_xp->evaluate('count(//node())');
$old_xml = $old_dom->saveXML();
...

// $new_dom is the modified document, must tested at each "black box" change.
$new_xp = new DOMXpath($new_dom);
$new_n = $new_xp->evaluate('count(//node())');
if ($new_n!=$old_n) {  //  OK, fast!!
  //.. OK! do something because changed!
} // else, check with more detail if changed,
elseif ($new_dom->saveXML()!=$old_xml){ // memory and CPU-time consuming here!
  //.. OK! do something because changed!
}




正如@ArtisiticPhoenix所建议的,让我们进行比较!


As @ArtisiticPhoenix suggested, let's compare!

Benchmarking rel = nofollow noreferrer>这个简单的要点和 PubMed Central的真实XML文档

BENCHMARKING by this simple gist and real life XML-documents of PubMed Central:

  $xp = new DOMXpath($dom);      
  $test = ( $xp->evaluate('count(//node())') == 123 );
    // Execution total time of 10000 loops: 0.582 seconds
    // Averaged execution time of each loop: 5.8152985572815E-5 seconds
  
  $xp = new DOMXpath($dom);      
  $test = ( $xp->evaluate('count(//*)') == 123 );
    // Execution total time of 10000 loops: 0.462 seconds
    // Averaged execution time of each loop: 4.6241903305054E-5 seconds

〜与其他解决方案相比要好10倍,

~10x better when comparing with another solutions,

  $test = ( md5( $dom->saveXML() ) == 'ff1afedc7127eb221050fa48eee5153a');
    // Execution total time of 10000 loops: 3.877 seconds
    // Averaged execution time of each loop: 0.00038769061565399 seconds

  $test = ( $dom->saveXML() == $oldXml ); // comparing long strings 
    // Execution total time of 10000 loops: 3.168 seconds
    // Averaged execution time of each loop: 0.00031677310466766 seconds

  $test = ( $dom->C14N() == $oldXml ); // comparing long strings 
    // Execution total time of 10000 loops: 8.874 seconds
    // Averaged execution time of each loop: 0.00088736770153046 seconds

注意:直接的 longString比较比md5 的 shortString快。确认,

NOTE: the direct longString comparation is faster than shortString by md5. Confirmed with,

  $test = ( $dom->saveXML() == 'xxx' );
    //Execution total time of 10000 loops: 3.14 seconds
    //Averaged execution time of each loop: 0.00031396999359131 seconds

即使在错误的情况下(比较相同的字符串),长/短变化也不会改变 0.31微秒。比起短+ MD5的 0.39微秒,直接执行效果更好。

The long/short change, even in the wrost case (comparing same string), not changes the "0.31 microseconds" to perform direct, better than short+MD5's "0.39 microseconds".

...是一个 DomDocument 内部属性,该属性返回 DOM length

... is a DomDocument internal property that returns the "DOM length" or "DOM number of nodes", without need of a XPath counting procedure.

PS:替代解决方案的赏金;或无需 XPath计数过程。是用于这种答案。

PS: a bounty for "alternative solution" is for this kind of answer.

这篇关于如何通过简单快速的比较检查DomDocument是否已更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆