簡體   English   中英

查找 xmls 之間的 delta 差異並列出 Xquery 中的差異

[英]To find delta difference between xmls and list the difference in Xquery

我試圖按照以下步驟找到兩個 xml 之間的區別。

  1. 獲取左右 xml 的內部子元素的所有不同路徑。
  2. 循環遍歷左側路徑並檢查它是否與任何右側路徑匹配。
  3. 如果不匹配,則它是一個新元素。
  4. 如果匹配,我正在做子元素的 map1-map2。這給了我改變的子元素(元素和屬性都改變)。

但我需要確定發生了什么變化,是元素文本還是屬性值並列出它。

請讓我知道 Xquery 中的一種方法來做到這一點。

比較 XML 並不完全是微不足道的,但它已經被經常嘗試了。 不是最新的,但你可以看看這個:

https://github.com/ryanjdew/marklogic-xml-diff

我過去也用過這個,雖然是 XSLT 而不是 XQuery,而且沒有那么詳細。 不過對於回歸測試效果很好,也可以在 MarkLogic 中使用:

http://xsltunit.org/xsltunit.xsl

還有一些商業產品,例如:

https://www.deltaxml.com/

雖然,不確定以上是否也可以以無頭方式使用..

哼!

正如 grtjn 指出的那樣,比較 XML 會變得非常復雜,特別是如果您的 XML 包含混合內容,或者如果您關心元素排序,或者您的元素可能出現多次。 如果這些都不適用,那么可以采取一些捷徑。

在您的示例中,將屬性添加到路徑列表中,然后僅根據字符串內容比較所有內容(元素和屬性)可能就足夠了。

路徑列表必須包含屬性。 您可以像這樣使用不同軸的聯合,或者您必須包含屬性和葉元素並排除文本節點和非葉元素的任何標准。

local:path-to-node($left/child::*/child::*/(self::*[text()]|attribute::*))

並且您的path-to-node功能必須能夠處理被傳遞的屬性。 因此,您必須對path-to-node函數進行一些更改,以確保正確命名屬性(使用“@”),並且(如果適用)不會獲得位置標記

declare function local:path-to-node($node as node()){
  let $attr := typeswitch ($node) case attribute() return '@' default return ()
  return string-join(('', $node/ancestor::*/name(.), $attr||name($node)), '/')
};

根據您的path-to-node函數的復雜程度,擁有其中兩個可能更容易。

fn:distinct-values((
  local:path-to-element-node($left/child::*/child::*),
  local:path-to-attribute-node($left/child::*/child::*/@*)
))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM