根据存储在另一个元素中的键选择 XML 个元素

Selecting XML Elements Based On Keys Stored In Another Element

不熟悉 xsl,如果这是一个常见问题,我深表歉意 -

我有一些 xml 看起来像这样(示例已简化,但我正在使用它):

<root>
  <items>
    <item>
      <value>1</value>
      <id>1</id>
    </item>
    <item>
      <value>2</value>
      <id>2</id>
    </item>
    <item>
      <value>99</value>
      <id>3</id>
    </item>
  </items>
  <itemList>
    <id>1</id>
    <id>2</id>
  </itemList>
</root>

我的用例是这样的:我需要从项目列表中获取 ID,然后使用这些 ID 来识别 "items" 中的项目。然后我需要获取项目的值并通过聚合传递任意数量的项目以获得我需要的最终结果("sumItems" 是我实现的更复杂的递归模板的替代品) .这是我到目前为止的 xsl,我正在尝试优化顶部的 with-param select 属性:

  <xsl:template match="*">
    <xsl:call-template name="sumItems">
      <xsl:with-param name="nodeSet" select="//item/id[text()=1 or text()=2]/.." />
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="sumItems">
    <xsl:param name="nodeSet" />
    <xsl:param name="tempSum" select="0" />

    <xsl:choose>
      <xsl:when test="not($nodeSet)">
        <xsl:value-of select="$tempSum" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="value" select="$nodeSet[1]/value" />
        <xsl:call-template name="sumItems">
          <xsl:with-param name="nodeSet" select="$nodeSet[position() > 1]" />
          <xsl:with-param name="tempSum" select="$tempSum + $value" />
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

我是否可以做这样的事情,在 select 中挂出某种子查询?

 select="//item/id[text()=(//itemList/id)]/.."

我 运行 来自 .Net XslCompiledTransform,如果相关的话。

我不知道这会让我觉得自己更聪明还是更笨,但是当我把它扔到我的 xsl 中时,我在问题底部发布的暗中猜测实际上似乎奏效了。 .我什至没有遇到语法错误。很抱歉给您带来麻烦 - 这是工作代码:

<xsl:template match="*">
    <xsl:call-template name="sumItems">
      <xsl:with-param name="nodeSet" select="//item/id[text()=(//itemList/id)]/.." />
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="sumItems">
    <xsl:param name="nodeSet" />
    <xsl:param name="tempSum" select="0" />

    <xsl:choose>
      <xsl:when test="not($nodeSet)">
        <xsl:value-of select="$tempSum" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="value" select="$nodeSet[1]/value" />
        <xsl:call-template name="sumItems">
          <xsl:with-param name="nodeSet" select="$nodeSet[position() > 1]" />
          <xsl:with-param name="tempSum" select="$tempSum + $value" />
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

使用用 <xsl:key name="item-by-id" match="items/item" use="id"/> 声明的键,然后您可以使用 key('item-by-id', //itemList/id) 到 select item 元素引用的 itemList/id 元素并使用 sum(key('item-by-id', //itemList/id)/value) 来计算 value 个元素的总和。