对我的业余 XML / XSLT 知识表示歉意 - 仍在学习。我希望我在下面提供了足够的细节。
我最近了解了如何使用 xsl“键”进行查找。我现在尝试将其应用于具有多个单独子节点的文件,每个子节点应该有自己的 单独 查找,但我不知道如何将 key 语句放在 for- 中每个循环。
简单示例输入:
<?xml version="1.0" encoding="UTF-8"?>
<file>
<record>
<data>
<item>2</item>
<item>4</item>
<item>6</item>
</data>
<names>
<person><id>1</id><name>Anton</name></person>
<person><id>2</id><name>Bruce</name></person>
<person><id>3</id><name>Chris</name></person>
<person><id>4</id><name>Dirk</name></person>
<person><id>5</id><name>Erik</name></person>
<person><id>6</id><name>Fred</name></person>
</names>
</record>
<record>
<data>
<item>1</item>
<item>2</item>
<item>5</item>
</data>
<names>
<person><id>1</id><name>Sue</name></person>
<person><id>2</id><name>Jen</name></person>
<person><id>3</id><name>Jill</name></person>
<person><id>4</id><name>Jane</name></person>
<person><id>5</id><name>Maria</name></person>
<person><id>6</id><name>Mary</name></person>
</names>
</record>
</file>
想法是使用 data/item 值在同一 record 节点中查找相应的 names/person/id 并返回 name。
期望的输出
<results>
<result>
<item>2</item>
<name>Bruce</name>
</result>
<result>
<item>4</item>
<name>Dirk</name>
</result>
<result>
<item>6</item>
<name>Fred</name>
</result>
</results>
<results>
<result>
<item>1</item>
<name>Sue</name>
</result>
<result>
<item>2</item>
<name>Jen</name>
</result>
<result>
<item>5</item>
<name>Maria</name>
</result>
</results>
但是,我的理解是密钥需要位于顶层,但是当我使用密钥“查找”值时,它会返回与项目编号匹配的所有条目(来自所有条目)子节点)。
XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="k1" match="file/record/names/person" use="id" />
<xsl:template match="file/record">
<results>
<xsl:for-each select="data/item">
<result>
<xsl:copy-of select="."/>
<xsl:copy-of select="key('k1', .)/name"/>
</result>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
错误的结果是它在名称上加倍,因为它在整个文档中找到了多个匹配的条目。
输出不正确:
<results>
<result>
<item>2</item>
<name>Bruce</name>
<name>Jen</name>
</result>
<result>
<item>4</item>
<name>Dirk</name>
<name>Jane</name>
</result>
<result>
<item>6</item>
<name>Fred</name>
<name>Mary</name>
</result>
</results>
<results>
<result>
<item>1</item>
<name>Anton</name>
<name>Sue</name>
</result>
<result>
<item>2</item>
<name>Bruce</name>
<name>Jen</name>
</result>
<result>
<item>5</item>
<name>Erik</name>
<name>Maria</name>
</result>
</results>
知道如何为每个记录进行独立的键/查找吗?
非常感谢您的专家建议。
亲切的问候, 阿杰
这在 XSLT 1.0 中很难实现,因为正如您所说,密钥的范围是文档范围的。原则上,只要您的处理器提供 xx:node-set() 扩展,您就可以将子树复制到变量中的新文档,并且如果上下文项是该变量中的节点,则 key 函数将搜索子树。但当然它会返回由键标识的复制节点,而不是原始节点。
更高版本的 XSLT 提供了更多的灵活性。事实上,在 XSLT 3.0 中,您可以使用映射而不是键,这允许您定义跨多个文档的索引。