0

我有以下XML代码:

<training_center>
<course id="XML">
    <title>Course 1</title>
    <keywords>
        <keyword>XML</keyword>
        <keyword>XPath</keyword>
    </keywords>
    <teachers>
        <teacher>Nikitin</teacher>
        <teacher>Pavlov</teacher>
    </teachers>
</course>
<course id="AJAX">
    <title>Course 2</title>
    <keywords>
        <keyword>AJAX</keyword>
        <keyword>XML</keyword>
    </keywords>
    <teachers>
        <teacher>Nikitin</teacher>
        <teacher>Chebykin</teacher>
    </teachers>
</course>
</training_center>

以及以下XSL代码:

<xsl:key 
    name='concat_key'
    match="/training_center/course"
    use="concat(teachers/teacher, ':', keywords/keyword)"
/>
<xsl:template match="/">                
    <xsl:apply-templates select="key('concat_key', concat('Nikitin',':','XML'))" />
</xsl:template>
<xsl:template match="course">
    <xsl:element name="course">         
        <xsl:value-of select="./title" />
    </xsl:element>
</xsl:template>

XSL 转换课程 1仅显示。但从逻辑上讲,课程 2也应显示。
在什么错误?

4

2 回答 2

0

我假设您使用的是 XSLT 1.0,因为... [基于您的结果的有根据的猜测]。

首先,您的方法无法工作的原因是该concat()函数适用于string-values,而不是node-sets

concat(teacher, ':', keyword)

被评估为:

concat(string(teacher), ':', string(keyword))

并且(在 XSLT 1.0 中)返回集合中第一个节点string(node-set)的字符串值。

您可以使用其他方法来实现目标,例如:

1. 使用带有谓词的键:

<xsl:key name="course-by-teacher" match="course" use="teachers/teacher" />

<xsl:template match="/">
    <output>
        <xsl:apply-templates select="key('course-by-teacher', Nikitin')[keywords/keyword='XML']" />
    </output>
</xsl:template>

<xsl:template match="course">
    <course>         
        <xsl:value-of select="title" />
    </course>
</xsl:template>

2.使用两个键的交集:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:set="http://exslt.org/sets"
extension-element-prefixes="set">
<xsl:output method='xml' version='1.0' encoding='utf-8' indent='yes'/>

<xsl:key name="course-by-teacher" match="course" use="teachers/teacher" />
<xsl:key name="course-by-keyword" match="course" use="keywords/keyword" />

<xsl:template match="/">
    <output>
        <xsl:apply-templates select="set:intersection(key('course-by-teacher', 'Nikitin'), key('course-by-keyword', 'XML'))" />
    </output>
</xsl:template>

<xsl:template match="course">
    <course>         
        <xsl:value-of select="title" />
    </course>
</xsl:template>

</xsl:stylesheet>

请注意,此方法需要set:intersection()许多 XSLT 1.0 处理器支持的 EXSLT 功能 - 但不是全部。如有必要,我将发布一个(更复杂的)方法,该方法可以在 XSLT 1.0 中本地生成两个节点集的交集。

于 2014-02-22T03:05:57.757 回答
0

concat(teachers/teacher, ':', keywords/keyword) will concat first teachers/teacher, ':', and first keywrods/keyword for every training_center/course. But in your second "course" AJAX is the first "keyword".

于 2014-02-21T18:32:20.560 回答