У меня есть следующая проблема в xslt. Учитывая пример XML:Как выводить в xslt под произвольный путь?
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>A</cd>
<dvd id='A'>B</dvd>
<dvd id='B'>C</dvd>
</catalog>
Я хочу теги вывода cd
в CD
и dvd[@id="B"]
в CD
, а все остальные dvd
как DVD
. Простое преобразование с трех шаблонов (CD, DVD и двд с ид = B) отлично работает, но выдает что-то вроде этого:
<CD>A</CD>
<DVD>B</DVD>
<CD>C</CD>
Проблема заключается в том, что схема проверки ожидает DVD
с, чтобы следовать CD
с, так CD -> DVD-> CD неправильный. Я придумал эту схему для решения этого:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="catalog">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="cd">
<CD>
<xsl:value-of select="."/>
</CD>
<xsl:if test="../dvd[@id='B']">
<xsl:apply-templates select="../dvd[@id='B']" mode="keep"/>
</xsl:if>
</xsl:template>
<xsl:template match="dvd">
<DVD>
<xsl:value-of select="."/>
</DVD>
</xsl:template>
<xsl:template match="dvd[@id='B']" mode="keep">
<CD>
<xsl:value-of select="."/>
</CD>
</xsl:template>
<xsl:template match="dvd[@id='B']">
<!-- do nothing -->
</xsl:template>
</xsl:stylesheet>
Это делает работу, но, кажется, немного многословными и сложным - я hackingly проверке, если узел существует, превращая его, и когда это происходит в нормальном поток обработки я игнорирую это - и я даже не уверен, что это абсолютно правильно.
Не могли бы вы предложить способ, которым dvd[@id="B"]
будет иметь только один шаблон, который будет выводить <CD>
под дорогой, например, «после последнего компакт-диска на этом уровне»?
Doh ... Большое спасибо :) Это такой вид мышления xslt, который трудно понять самостоятельно, но как только вы там, он имеет прекрасный смысл и поможет мне решить еще много проблем в будущем. – backflip
Btw с точки зрения неформации, примеры были просто упрощением гораздо более сложной реальной проблемы. – backflip