XSLT:根据当前上下文读取其他节点的值

问题描述

人,

我有一个结构如下的 XML:

<root>
  <concepts>
    <concept id="1" version="1">
      <name>This is the name of 1.1</name>
    </concept>
    <concept id="1" version="2">
      <name>This is the name of 1.2</name>
    </concept>
    <concept id="2" version="1">
      <name>This is the name of 2.1</name>
    </concept>
  </concepts>
  <structures>
    <structure id="1">
      <conceptRef id="2" version="1" />
    </structure>
    <structure id="2">
      <conceptRef id="1" version="2" />
    </structure>
  </structures>
</root>

我想根据结构/概念引用子节点中的属性获取概念的名称子节点中的文本。上面例子的输出应该是这样的:

  • 结构 1:这是 2.1 的名称
  • 结构 2:这是 1.2 的名称

所以我目前有这样的事情:

<xsl:template match="structures">
  <xsl:for-each select=".//structure">
    Structure <xsl:value-of select="@id" />: <!-- Todo: what goes here -->
  </xsl:for-each>
</xsl:template>

我不知道的是,我如何嵌套 XPath 查询以根据当前上下文从其他树中查找节点。出于调试目的,我现在添加了三个不同的行来测试该方法

    <xsl:template match="structures">
        <xsl:for-each select=".//structure">
            Structure <xsl:value-of select="@id" />: 
             0: <xsl:value-of select="./conceptRef/@id" />.<xsl:value-of select="./conceptRef/@version" />
             a: <xsl:value-of select="//concepts/concept[@id=./conceptRef/@id and @version=./conceptRef/@version]/name" />
             b: <xsl:value-of select="//concepts/concept[@id=1 and @version=2]/name" />
        </xsl:for-each>
    </xsl:template>

输出为:

            Structure 1: 
             0: 2.1
             a: 
             b: This is the name of 1.2
            Structure 2: 
             0: 1.2
             a: 
             b: This is the name of 1.2

这意味着小于 0 的值会为过滤器提供正确的值。在第 2 行中,我看到了同样有效的硬编码值。就在我将两者在 a 行中合并时,结果由于某种原因为空。

有什么想法吗?

谢谢, 丹尼尔。

解决方法

我强烈建议使用 key 来解决交叉引用。以下样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:key name="concept" match="concept" use="concat(@id,'|',@version)" />

<xsl:template match="/root">
    <xsl:for-each select="structures/structure">
        <xsl:text>Structure </xsl:text>
        <xsl:value-of select="@id" />
        <xsl:text>: </xsl:text>
        <xsl:value-of select="key('concept',concat(conceptRef/@id,conceptRef/@version))/name" />
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,将产生:

结果

Structure 1: This is the name of 2.1
Structure 2: This is the name of 1.2
,

您想使用 current() 函数,例如//concepts/concept[@id=current()/conceptRef/@id and @version=current()/conceptRef/@version]/name 为您的工作路径。为了提高效率,您可能希望通过声明一个键并使用键函数来替换该查找。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...