XSLT 使用额外的 for-each 或使用 Muenchian 方法应用模板?
XSLT using extra for-each or apply-templates using Muenchian method?
我已经开始学习 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>
使用这两个的特定解决方案更好吗?或者你推荐其中的哪一个,为什么?
一旦您定义了键并想要访问组中的项目,使用 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-templates
和模式来消除:
<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>
我已经开始学习 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>
使用这两个的特定解决方案更好吗?或者你推荐其中的哪一个,为什么?
一旦您定义了键并想要访问组中的项目,使用 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-templates
和模式来消除:
<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>