比较两个 xml 树节点,并使用 xslt 查找具有值的节点是否存在于另一个节点中
Compare two xml tree nodes and find if a node with a value exists in another using xslt
我有一个 XML 输入,它是两个 xml 的合并格式:
<DATA>
<RECORDS1>
<RECORD>
<id>11</id>
<value>123</value>
</RECORD>
<RECORD>
<id>33</id>
<value>321</value>
</RECORD>
<RECORD>
<id>55</id>
<value>121113</value>
</RECORD>
...
</RECORDS1>
<RECORDS2>
<RECORD>
<id>11</id>
<value>123</value>
</RECORD>
<RECORD>
<id>33</id>
<value>323</value>
</RECORD>
<RECORD>
<id>44</id>
<value>12333</value>
</RECORD>
...
</RECORDS2>
我需要在输出中复制提供的 RECORDS1 中的记录:
- RECORDS1 中的记录在 RECORDS2 中不存在
- RECORDS1中的记录在RECORDS2中存在但值不同
此外,如果可以扩展输出,例如使用值为 NEW(当不存在时)作为 CHANGE(当存在但值不同时)的额外字段
输出
<DATA>
<RECORDS>
<RECORD>
<id>33</id>
<value>321</value>
<kind>Change</kind>
</RECORD>
<RECORD>
<id>55</id>
<value>121113</value>
<kind>New</kind>
</RECORD>
...
</RECORDS>
我已经应用了 FOR 循环,但由于无法重置 xslt 中的变量,因此它不起作用。
有什么想法吗?
也许
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="rec2-complete" match="RECORDS2/RECORD" use="concat(id, '|', value)"/>
<xsl:key name="rec2-id" match="RECORDS2/RECORD" use="id"/>
<xsl:template match="DATA">
<xsl:apply-templates select="RECORDS1/RECORD[not(key('rec2-complete', concat(id, '|', value)))]"/>
</xsl:template>
<xsl:template match="RECORDS1/RECORD">
<xsl:copy>
<xsl:copy-of select="node()"/>
<merged>
<xsl:value-of select="if (key('rec2-id', id)/value != value) then 'changed' else 'new'"/>
</merged>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
执行要求。
或者,要构建您现在显示的完整结果,请使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="rec2-complete" match="RECORDS2/RECORD" use="concat(id, '|', value)"/>
<xsl:key name="rec2-id" match="RECORDS2/RECORD" use="id"/>
<xsl:template match="DATA">
<xsl:copy>
<RECORDS>
<xsl:apply-templates select="RECORDS1/RECORD[not(key('rec2-complete', concat(id, '|', value)))]"/>
</RECORDS>
</xsl:copy>
</xsl:template>
<xsl:template match="RECORDS1/RECORD">
<xsl:copy>
<xsl:copy-of select="node()"/>
<kind>
<xsl:value-of select="if (key('rec2-id', id)/value != value) then 'change' else 'new'"/>
</kind>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有一个 XML 输入,它是两个 xml 的合并格式:
<DATA>
<RECORDS1>
<RECORD>
<id>11</id>
<value>123</value>
</RECORD>
<RECORD>
<id>33</id>
<value>321</value>
</RECORD>
<RECORD>
<id>55</id>
<value>121113</value>
</RECORD>
...
</RECORDS1>
<RECORDS2>
<RECORD>
<id>11</id>
<value>123</value>
</RECORD>
<RECORD>
<id>33</id>
<value>323</value>
</RECORD>
<RECORD>
<id>44</id>
<value>12333</value>
</RECORD>
...
</RECORDS2>
我需要在输出中复制提供的 RECORDS1 中的记录:
- RECORDS1 中的记录在 RECORDS2 中不存在
- RECORDS1中的记录在RECORDS2中存在但值不同
此外,如果可以扩展输出,例如使用值为 NEW(当不存在时)作为 CHANGE(当存在但值不同时)的额外字段
输出
<DATA>
<RECORDS>
<RECORD>
<id>33</id>
<value>321</value>
<kind>Change</kind>
</RECORD>
<RECORD>
<id>55</id>
<value>121113</value>
<kind>New</kind>
</RECORD>
...
</RECORDS>
我已经应用了 FOR 循环,但由于无法重置 xslt 中的变量,因此它不起作用。
有什么想法吗?
也许
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="rec2-complete" match="RECORDS2/RECORD" use="concat(id, '|', value)"/>
<xsl:key name="rec2-id" match="RECORDS2/RECORD" use="id"/>
<xsl:template match="DATA">
<xsl:apply-templates select="RECORDS1/RECORD[not(key('rec2-complete', concat(id, '|', value)))]"/>
</xsl:template>
<xsl:template match="RECORDS1/RECORD">
<xsl:copy>
<xsl:copy-of select="node()"/>
<merged>
<xsl:value-of select="if (key('rec2-id', id)/value != value) then 'changed' else 'new'"/>
</merged>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
执行要求。
或者,要构建您现在显示的完整结果,请使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="rec2-complete" match="RECORDS2/RECORD" use="concat(id, '|', value)"/>
<xsl:key name="rec2-id" match="RECORDS2/RECORD" use="id"/>
<xsl:template match="DATA">
<xsl:copy>
<RECORDS>
<xsl:apply-templates select="RECORDS1/RECORD[not(key('rec2-complete', concat(id, '|', value)))]"/>
</RECORDS>
</xsl:copy>
</xsl:template>
<xsl:template match="RECORDS1/RECORD">
<xsl:copy>
<xsl:copy-of select="node()"/>
<kind>
<xsl:value-of select="if (key('rec2-id', id)/value != value) then 'change' else 'new'"/>
</kind>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>