我已经有了新问题。 我必须通过xsl合并列表,问题是查找列表中的键必须由2个值进行同步。 这些列表可能相对较大,有数千个,在某些情况下可能会有两万个列表中的更多条目。在此列表的大尺寸之前,我必须关注性能和内存。可能以后会在Web服务客户端中实现,因此必须快速运行并节省资源。
合并List1和List2中的现有元素已经完成并且并不复杂,但现在我必须检查其他列表中的非现有元素上的两个列表。 我试图否定for-each select语句但是失败了,这可能是错误的方式。
InputXML-示例
<ROOT>
<getObjectListResponse>
<item>
<Key>1111111:aaaa</Key>
<someOhterData>Text</someOhterData>
</item>
<item>
<Key>2222222:bbbb</Key>
<someOhterData>Text</someOhterData>
</item>
<item>
<Key>3333333:aaaa</Key>
<someOhterData>Text</someOhterData>
</item>
</getObjectListResponse>
<LookupList>
<DATA>
<KeyPart1>1111111</KeyPart1>
<KeyPart2>aaaa</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>1111111</KeyPart1>
<KeyPart2>bbbb</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>2222222</KeyPart1>
<KeyPart2>aaaa</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>2222222</KeyPart1>
<KeyPart2>bbbb</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>3333333</KeyPart1>
<KeyPart2>aaaa</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>3333333</KeyPart1>
<KeyPart2>bbbb</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
</LookupList>
</ROOT>
第一部分,找到两个列表中的现有部分已经完成。 第二部分是在列表1到列表2和列表2到列表1中查找不存在的部分。 我想在for-each中执行此操作,因此您只能从List1获取List2中不存在的非现有条目。 我的问题是从LookupList中的所有DATA中使用连接键在for-each上下文中查找。
<xsl:for-each select="/*/getObjectListResponse/item[Key/text() != /*/LookupList/DATA/*[concat(KeyPart1,'/',KeyPart2)]]">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:for-each select="/*/getObjectListResponse/item[Key/text() != /*/LookupList/DATA/[concat(KeyPart1,'/',KeyPart2)]]">
<xsl:copy-of select="."/>
</xsl:for-each>
但我尝试的一切都失败了,没有结果或错误的结果。
如何做到这一点?
我尝试了这个以及其他一些,但没有任何作用。
提前致谢
答案 0 :(得分:2)
我会使用密钥进行交叉引用,这里是一个XSLT 3.0(由Saxon 9.8所有版本或Altova XMLSpy / Raptor支持)样式表,因为很明显一个示例是复合键的一个很好的用例:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:output indent="yes"/>
<xsl:key name="data" match="DATA" composite="true" use="KeyPart1, KeyPart2"/>
<xsl:key name="item" match="item" use="Key"/>
<xsl:template match="ROOT">
<xsl:copy>
<items-not-in-data>
<xsl:copy-of select="getObjectListResponse/item[not(key('data', (substring-before(Key, ':'), substring-after(Key, ':'))))]"/>
</items-not-in-data>
<data-not-in-items>
<xsl:copy-of select="LookupList/DATA[not(key('item', concat(KeyPart1, ':', KeyPart2)))]"/>
</data-not-in-items>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我的样本数据
<ROOT>
<items-not-in-data/>
<data-not-in-items>
<DATA>
<KeyPart1>1111111</KeyPart1>
<KeyPart2>bbbb</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>2222222</KeyPart1>
<KeyPart2>aaaa</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
<DATA>
<KeyPart1>3333333</KeyPart1>
<KeyPart2>bbbb</KeyPart2>
<someOhterData>Text</someOhterData>
</DATA>
</data-not-in-items>
</ROOT>
当然,XSLT 3.0和复合键不是必需的,您也可以使用XSLT 2.0并使用单个键值concat(KeyPart1, KeyPart2)
。