2014-02-21 3 views
0

У меня есть следующий XML код:XML/XSLT - XSL: ключ CONCAT

<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 также должен быть показан.
В чем ошибка?

+0

Вы используете XSLT 1.0 или 2.0? –

+0

Я использую XSLT 1.0 – ollazarev

ответ

0

Я предполагаю, что вы используете XSLT 1.0, потому что ... [образованное предположение, основанное на вашем результате].

Во-первых, причина, почему ваш метод не может работать в том, что функция concat() работает на строковых значений, а не множества узлов.

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> 

Обратите внимание, что этот метод требует EXSLT set:intersection() которая поддерживается многими процессорами XSLT 1.0, но не все из них. При необходимости я отправлю (более сложный) метод, который может привести к пересечению двух наборов узлов изначально в XSLT 1.0.

+0

Большое спасибо. Да, пошлите пожалуйста. В * XSLT 2.0 * моя цель будет достигнута? – ollazarev

+0

Почему вы не читали об этом в источнике: http://books.google.com/books?id=Xw3_tzEJVEwC&pg=PA237&lpg=PA237&dq=xpath+2.0+intersect&source=bl&ots=03ToDMmtbI&sig=2lkuI4eV_UDOcHm6hRdfJpIyCo0&hl=en&sa=X&ei=M7MHU90Xo4rsBu7YgcgK&ved = 0CHAQ6AEwBw # v = onepage & q = xpath% 202.0% 20intersect & f = false В нем также обсуждается XSLT 2.0. –

+0

Благодарю за ссылку. – ollazarev

0

concat (учитель/преподаватель, ':', ключевые слова/ключевое слово) будет конкат первым учителем/преподавателем ':' и первым keywrods/keyword для каждого учебного центра/курса. Но во втором «курсе» AJAX - это первое «ключевое слово».

+0

Вы можете решить эту проблему, используя 'concat'? – ollazarev

+0

Это ваше требование, чтобы выбрать «курс», который содержит учитель = «Никитин» и ключевое слово = «XML»? –

+0

Да и желательно использовать 'concat' xsl: key – ollazarev

Смежные вопросы