我有两个文档要比较,但我想省略两个节点的比较,因为我知道这两个节点将是不同的,例如。
<record>
<core>
<title>test1</title>
<description>testDesc1</description>
<ingestDate>2019-03-01</ingestDate>
</core>
<specialized>
<item>testItem1</item>
<itemRecordingTime>2019-12-05T08:15:00</itemRecordingTime>
</specialized>
</record>
和
<record>
<core>
<title>test1</title>
<description>testDesc1</description>
<ingestDate>2020-03-01</ingestDate>
</core>
<specialized>
<item>testItem1</item>
<itemRecordingTime>2020-12-05T08:15:00</itemRecordingTime>
</specialized>
</record>
除了节点之外,在xquery或xpath中是否有任何方法来比较这两个文档。<ingestDate>
和 <itemRecordingTime>
?
我会对内容进行标准化处理,去掉不想比较的元素,然后用 fn:deep-equal()
来比较规范化的文档。
下面是一个例子,说明如何使用XSLT来移除元素,并使用 xdmp:xslt-eval()
(你也可以 xdmp:xslt-invoke
安装的样式表,而不是eval)。)
xquery version "1.0-ml";
declare function local:compare($a, $b) {
let $xslt :=
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--Remove the elements that we don't want to compare -->
<xsl:template match="ingestDate | itemRecordingTime"/>
</xsl:stylesheet>
let $normalized-a := xdmp:xslt-eval($xslt, $a)
let $normalized-b := xdmp:xslt-eval($xslt, $b)
return fn:deep-equal($normalized-a, $normalized-b)
};
let $doc-a :=
<record>
<core>
<title>test1</title>
<description>testDesc1</description>
<ingestDate>2019-03-01</ingestDate>
</core>
<specialized>
<item>testItem1</item>
<itemRecordingTime>2019-12-05T08:15:00</itemRecordingTime>
</specialized>
</record>
let $doc-b :=
<record>
<core>
<title>test1</title>
<description>testDesc1</description>
<ingestDate>2020-03-01</ingestDate>
</core>
<specialized>
<item>testItem1</item>
<itemRecordingTime>2020-12-05T08:15:00</itemRecordingTime>
</specialized>
</record>
return
local:compare($doc-a, $doc-b)
替代方法。你可以使用XPath来提取文本节点,并对它们进行连接。将结果存储在2个变量中并进行比较。
XPath 2.0 :
string-join(//*/*[position()<last()]/text()[normalize-space()])
或
string-join(//*[not(name()="ingestDate" or name()="itemRecordingTime")]/text()[normalize-space()])
输出:
String='test1testDesc1testItem1'
XPath 1.0 (massive) :
translate(concat(substring(normalize-space(string(//core)),1,string-length(normalize-space(string(//core)))-(string-length(normalize-space(string(//ingestDate)))+1)),substring(normalize-space(string(//specialized)),1,string-length(normalize-space(string(//specialized)))-(string-length(normalize-space(string(//itemRecordingTime)))+1)))," ","")
输出:XPath 1.0 (massive)
String='test1testDesc1testItem1'