2010-06-07 2 views
3

Я пытаюсь применить преобразование XSLT к пакетной документации XML. Главной точкой преобразования является переупорядочение нескольких элементов. Я хочу, чтобы сохранить какие-либо комментарии, которые непосредственно предшествует элемент:xslt & xpath: соответствие непосредственно предшествующим комментариям

<!-- not this comment --> 
<element /> 

<!-- this comment --> 
<!-- and this one --> 
<element /> 

Ближайший я пришел к решению, чтобы использовать выражение:

<xsl:template match="element"> 
    <xsl:copy-of select="preceding-sibling::comment()"/> 
</xsl:template> 

который захватывает слишком много комментариев:

<!-- not this comment --> 
<!-- this comment --> 
<!-- and this one --> 

Я понимаю, почему вышеупомянутый XPath работает неправильно, но у меня нет хороших идей о том, как действовать. То, что я ищу что-то, чтобы выбрать все предыдущие комментарии, чьи следующий-родственный либо другой комментарий или текущий элемент обрабатываемый:

preceding-sibling::comment()[following-sibling::reference_to_current_element() or following-sibling::comment()] 

ответ

5
<xsl:template match="element"> 
    <xsl:copy-of select="preceding-sibling::comment()[ 
    generate-id(following-sibling::*[1]) = generate-id(current()) 
    "/> 
</xsl:template> 

Более эффективный:

<xsl:key 
    name = "kPrecedingComment" 
    match = "comment()" 
    use = "generate-id(following-sibling::*[1])" 
/> 

<!-- ... --> 

<xsl:template match="element"> 
    <xsl:copy-of select="key('kPrecedingComment', generate-id())" /> 
</xsl:template> 
+0

Спасибо, ваше решение отлично работает! Мне нужно сделать некоторые чтения на generate-id() и key(). –

+0

@Joshua Johnson: Что касается ключей: я написал что-то, что объясняет, как они работают на примере JavaScript, посмотрите, хотите ли вы: http://stackoverflow.com/questions/948218/xslt-3-level- grouping-on-attributes/955527 # 955527 (просто прочитайте нижнюю часть ответа). – Tomalak

1

Я думаю, наилучшим способом его можно было бы сделать следующее:

Я хочу, чтобы комментарии были точными, но только те, у которых текущий узел был первым элементом, который следует за ними.

Затем в xpath1.0/xslt1.0:

<xsl:template match="element"> 
<xsl:copy-of select="preceding-sibling::comment()[count(following-sibling::*[1]|current()) = 1]"/> 
</xsl:template> 
+0

+1 - Но этого не хватает короткого объяснения * почему * он работает. ;-) – Tomalak

+1

@ Томалак: Ты прав. Простите за это! Каждый узел в наборе узлов является disctint (в наборе узлов не дублируется «ссылка на узел»). Итак, чтобы проверить, что два узла на самом деле являются одним и тем же узлом, вам не нужна функция generate-id() (которая гарантирует уникальную строку идентификатора для узла в тот же процесс преобразования). Вам нужно только проверить, что объединение создает узел с одним узлом. Это сокращение для выражения идентификатора узла: «count ($ a | $ b) = count ($ b) и count ($ b) = count ($ a)". Извините за перевод, мой lenguage испанский. – 2010-06-07 17:21:54

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