XSLT 将键分隔为多个子节点的查找

问题描述 投票:0回答:1

对我的业余 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>

知道如何为每个记录进行独立的键/查找吗?

非常感谢您的专家建议。

亲切的问候, 阿杰

xml xslt key
1个回答
0
投票

这在 XSLT 1.0 中很难实现,因为正如您所说,密钥的范围是文档范围的。原则上,只要您的处理器提供 xx:node-set() 扩展,您就可以将子树复制到变量中的新文档,并且如果上下文项是该变量中的节点,则 key 函数将搜索子树。但当然它会返回由键标识的复制节点,而不是原始节点。

更高版本的 XSLT 提供了更多的灵活性。事实上,在 XSLT 3.0 中,您可以使用映射而不是键,这允许您定义跨多个文档的索引。

© www.soinside.com 2019 - 2024. All rights reserved.