0

我已经开始学习 XSLT,并且在练习中使用了 Muenchian 方法。我找到了2 种不同的方法来获得我的预期结果。带有apply-templates和 带有额外的for-each

钥匙:

<xsl:key name="tech" match="technology" use="."/>

使用应用模板的第一个解决方案:

<xsl:for-each select="//./technology[generate-id(.)=generate-id(key('tech', .)[1])]">
    <team>
        <xsl:variable name="selectedTech" select="."/>
        <xsl:apply-templates select="../../person[./technology=$selectedTech]">
    </team>
</xsl:for-each>

<xsl:template match="person">
    <member><xsl:value-of select="name"/></member>
</xsl:template>

使用额外的 for-each 的第二个解决方案:

<xsl:for-each select="//./technology[generate-id(.)=generate-id(key('tech', .)[1])]">
    <team>
        <xsl:variable name="selectedTech" select="."/>

        <xsl:for-each select="key('tech', .)">
            <member><xsl:value-of select="../name"/></member>
        </xsl:for-each>
    </team>
</xsl:for-each>

输入是这样的:

<employees>
    <person>
        <name>Bert</name>
        <technology>IBM</technology>
    </person>
    <person>
        <name>Jack</name>
        <technology>Microsoft</technology>
    </person>
    <person>
        <name>Karel</name>
        <technology>IBM</technology>
    </person>
    <person>
        <name>Bill</name>
        <technology>Microsoft</technology>
    </person>
    <person>
        <name>Joris</name>
        <technology>OpenSource</technology>
    </person>
    <person>
        <name>Piet</name>
        <technology>OpenSource</technology>
    </person>
</employees>

使用这两个的特定解决方案会更好吗?或者你推荐其中哪一个,为什么?

4

1 回答 1

2

一旦您定义了一个键并想要访问组中的项目,使用它key('key-name', keyValueExpression)来执行此操作肯定会更有效,而不是遍历轴并编写谓词。

所以在我看来,而不是../../person[./technology=$selectedTech](我想知道它是否不需要../person[./technology=$selectedTech]),我肯定会用它key('tech', .)来查找组中的项目。

apply-templates或之间的决定for-each是另一个问题,因为您可以同时使用两者。

通常使用apply-templates和分离模板,样式表结构更好,可读性更强,但对于快速和简短的 for-each 可能就足够了。

对于整个问题,我会定义关键person

<xsl:key name="tech" match="person" use="technology"/>


<xsl:for-each select="//person[generate-id(.)=generate-id(key('tech', technology)[1])]">
    <team>
        <xsl:apply-templates select="key('tech', technology)">
    </team>
</xsl:for-each>

<xsl:template match="person">
    <member><xsl:value-of select="name"/></member>
</xsl:template>

当然,第一个for-each也可以使用apply-templatesand 模式消除:

<xsl:key name="tech" match="person" use="technology"/>


<xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="//person[generate-id(.)=generate-id(key('tech', technology)[1])]" mode="team"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="person" mode="team">
    <team>
        <xsl:apply-templates select="key('tech', technology)">
    </team>
</xsl:for-each>

<xsl:template match="person">
    <member><xsl:value-of select="name"/></member>
</xsl:template>
于 2015-03-23T09:37:19.180 回答