【问题标题】:How to reference a node using a key -- XSLT如何使用键引用节点——XSLT
【发布时间】:2014-02-20 01:39:24
【问题描述】:

给定以下 xml 文档...

   <ws>
       <series year="2005" mvp="Jermaine Dye">
          <team name="Chicago White Sox" wins="4" />
          <team name="Houston Astros" wins="0" />
       </series>
       <series year="2004" mvp="Manny Ramirez">
          <team name="Boston Red Sox" wins="4" />
          <team name="St. Louis Cardinals" wins="0" />
       </series>
    </ws>

我已经创建了一个键来获取每个系列中第一支球队的名称属性,我正在尝试循环并列出每个系列的每个名称,如下所示;我目前没有返回任何结果,也不确定我的参考价值有什么问题?...

<xsl:key name="winners" match="team[1]" use="@name" />

    <xsl:template match="/">
        <xsl:for-each select="ws/series">
             <xsl:value-of select="key('winners', @name)" />
        </xsl:for-each>
    </xsl:template>

预期的输出将是......

Chicago White Sox (the first team from series 1)
Boston Red Sox (the first team from series 2)

我提供的 xml 数据仅包含 2 个系列元素,而实际上有数百个。该密钥用于加快转换过程,并与其他密钥一起生成我的结果文档。

【问题讨论】:

  • 为什么这里需要密钥?获胜者不是当前系列的第一个子团队吗?附言如果我们能看到所需的输出,这将更加清晰。
  • @michael.hor257k 我修改了我的帖子,希望对您有所帮助。我知道 for-each 循环运行良好,只是没有按我的意愿显示团队名称。

标签: xml xslt xslkey


【解决方案1】:

我正在尝试列出每个系列的第一支球队的名字

对于这样一个简单的任务,使用密钥是不必要的复杂化。尝试简单:

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="team[1]/@name" />
    </xsl:for-each>
</xsl:template>

当然,您会想要为此添加某种包装器或分隔符,否则您只会得到所有名称的混乱 - 比如说(假设输出方法是文本):

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="team[1]/@name" />
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

编辑:

要使用密钥(人为地)执行此操作,您必须问自己是什么将团队与其系列联系起来(而不是作为其子级)。这里的答案是“没有”。但是,团队可以访问其父系列数据。因此,我们可以通过其父系列的某些属性来识别团队,例如年份或 MVP。 MVP 可能不是该系列独有的,所以让我们确定关键:

<xsl:key name="team-by-year" match="team" use="parent::series/@year" />

这就是说:如果你告诉我那一年,我会告诉你那一年参加系列赛的球队。所以从这里开始,只需用当前系列的年份调用一个键即可:

<xsl:template match="/">
    <xsl:for-each select="ws/series">
        <xsl:value-of select="key('team-by-year', @year)[1]/@name" />
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

【讨论】:

  • 我没有选择使用密钥 :( 有没有用密钥来引用 name 属性?编辑:我相信使用密钥就像你相信的那样是不必要的但是,我正在尝试学习使用键来引用节点集。
  • "我无法选择使用密钥" 为什么?
  • 这是我正在进行的 xsl 练习的一部分,我正在尝试基本掌握如何使用给定键引用我需要的数据。
  • 未分配,我只是在阅读一本关于 XML 的书,并且正在做每一个练习来尝试提高我对内容的理解。事实证明,XSL 对我来说比 PHP 或 Java 过程或面向对象的编码方法要复杂得多。
  • 好吧,这不是一个好的练习,因为这里的正确答案是:不需要密钥。基本上,您是在询问如何向站在您旁边的人发送电报。无论如何,我已经编辑了我的答案以包含这个“方法”。
【解决方案2】:

如果你使用这个

<xsl:stylesheet version='1.0' xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <xsl:key name="winners" match="team[1]" use="@name" />

    <xsl:template match="/">
        <xsl:for-each select="ws/series/*">
            <xsl:value-of select="key('winners', @name)/@name" />
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多