Один из способов сделать это с вашим XML-кодом был бы следующим:
<xsl:template match="widget">
<!-- ... -->
<xsl:apply-templates select="." mode="create-date-time" />
<!-- ... -->
</xsl:template>
<xsl:template match="widget" mode="create-date-time">
<xsl:variable name="date" select="component[@name='date']" />
<xsl:variable name="time" select="component[@name='time']" />
<DateTime>
<xsl:value-of select="normalize-space(
concat(
$date/component[@name='day']/@label, ' ',
$date/component[@name='date']/@label, ' ',
$time/@label
)
)" />
</DateTime>
</xsl:template>
- Я передаю
widget[@name="date"]
каждому оператору выбора.Есть ли лучший способ сократить xpath.
Используйте <xsl:template>
/ <xsl:apply-templates>
и относительные пути.Храните вещи, которые вам нужны более одного раза, в <xsl:variable>
.См. Выше.
- Мне нужно переместить это в шаблон и вызвать шаблон.какой я должен использовать call-template / apply-templates?
Последний.Всегда переходите на <xsl:apply-templates>
, если нет веских причин не делать этого.Как правило: если вы не уверены, то для этого нет веской причины.
- У нас есть набор похожих приложений, которые генерируют эти XML.Приведенный выше XML взят из приложения A.Приложение B может показывать детали немного по-другому, что-то вроде
<component name="datetime">Fri 4 11:23 AM</component>
У нас есть почти 3-4 таких приложения, где они отображают детали немного по-другому.
Вы можете расширитьшаблон create-date-time
для этого:
<xsl:template match="widget" mode="create-date-time">
<xsl:variable name="date" select="component[@name='date']" />
<xsl:variable name="time" select="component[@name='time']" />
<xsl:variable name="dt" select="component[@name='datetime']" />
<DateTime>
<xsl:value-of select="normalize-space(
concat(
$dt/label, ' ',
$date/component[@name='day']/@label, ' ',
$date/component[@name='date']/@label, ' ',
$time/@label
)
)" />
</DateTime>
</xsl:template>
Если некоторые компоненты отсутствуют, ошибок не будет.normalize-space()
обеспечивает отсутствие лишних пробелов для любой комбинации компонентов.
Выше может произойти сбой, если компоненты date
+ time
и datetime
не являются взаимоисключающими (я предположил,они есть).Если это не так, или если возникают более сложные случаи, создайте дополнительные специальные шаблоны, такие как этот:
<xsl:template match="widget[component[name='datetime']]" mode="create-date-time">
<xsl:variable name="dt" select="component[@name='datetime']" />
<DateTime>
<xsl:value-of select="component[@name='datetime']/@label" />
</DateTime>
</xsl:template>
<xsl:apply-templates>
убедится, что вызывается правильный.Просто создайте конкретные match=
выражения для каждого возможного случая.