2013-09-26 2 views
1

С учетом этого исходного документа:Как «как» атрибут XSL: шаблон влияет на результат XSL: применить-шаблоны

<things> 
    <thing><duck>Eider</duck></thing> 
    <thing><duck>Mallard</duck></thing> 
    <thing><duck>Muscovy</duck></thing> 
</things> 

I требует следующих выходных данных

Fat Eider, Fat Mallard, Fat Muscovy 

, которые я могу действительно получить с этим XSL преобразования:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" > 
    <xsl:output method="text"/> 
    <xsl:template match="/"> 
    <xsl:value-of separator=", "> 
     <xsl:apply-templates select="//duck"/> 
    </xsl:value-of> 
    </xsl:template> 
    <xsl:template match="duck" as="xs:string"> 
    <xsl:value-of select="concat('Fat ', .)"/> 
    </xsl:template> 
</xsl:stylesheet> 

Однако, у меня есть три вопроса:

Вопрос 1. (специфические)

Если удалить as="xs:string" из шаблона утка, я получаю следующий результат:

Fat EiderFat MallardFat Muscovy 

Почему? Я понимаю, что в XSLT 2.0 результат xsl:apply-templates всегда является последовательностью и что xsl:value-of вставляет свой separator между элементами в последовательности. Итак, почему последовательность, похоже, «рушится», когда шаблон не имеет атрибута as? Бонусные баллы за то, что указали мне на соответствующие страницы отличной книги «XSLT 2.0 и XPath 2.0, 4th Edition» Майкла Кэя.

Вопрос 2. (расплывчатый!)

Как начинающий пользователь XSLT, мне кажется, что есть, вероятно, много способов решить эту проблему. Можете ли вы предложить хорошее решение, использующее другой подход? Как вы выбираете между подходами?

Вопрос 3.

Debugging. Можете ли вы рекомендовать, как вывести промежуточные результаты, которые указывают на разницу между присутствием и отсутствием атрибута as для template?

ответ

2

См http://www.w3.org/TR/xslt20/#value-of, который говорит

Значение строки нового текстового узла может быть определен либо с помощью избранных атрибутов, или с помощью конструктора последовательности (см 5.7 Sequence Конструкторы), что составляет содержание элемент xsl: value-of. Они являются взаимоисключающими, и один из них должен присутствовать. Способ , в котором построено значение, указан в 5.7.2. Построение Простой контент.

Таким образом, нам нужно посмотреть http://www.w3.org/TR/xslt20/#constructing-simple-content и что «2. Смежные текстовые узлы в последовательности объединены в один текстовый узел». Таким образом, это то, что происходит без as="xs:string", конструктор последовательности внутри xsl:value-of создает смежные текстовые узлы, которые объединены в один текстовый узел. Если у вас есть as="xs:string" или <xsl:sequence select="concat('Fat ', .)"/>, то конструктор последовательности имеет последовательность примитивных строковых значений.

+0

Мартин, спасибо вам за эти очень полезные указатели. Итак, правильно ли я говорю, что без атрибута 'as' результат« xsl: template »всегда будет иметь тип данных, который поступает из мира XDM/XPath (в отличие от мира XSchema)?- в случае моего шаблона утки - текстового узла. –

+1

Я не уверен, что вы термины «мир XDM/XPath» и «мир XSchema». Если вы пишете шаблон без атрибута 'as', его общим типом возврата является' item() * ', но он, конечно, может возвращать значение' xs: dateTime', например: '. С XSLT/XPath 2.0 или XQuery 1.0 модель данных представляет собой последовательности элементов, которые могут быть узлами или примитивными значениями (где типы данных этих значений берутся из или являются расширением типов данных схемы W3C). Таким образом, различие «XDM/XPath», противоположное «XSchema», на мой взгляд не существует. –

+0

«Мир XSchema», я имею в виду http://www.w3.org/TR/xmlschema-2/. Под «XDM/XPath world» я имею в виду http://www.w3.org/TR/xpath-datamodel/. Майкл Кей описывает их как «две разные, но перекрывающиеся категории [типов]». Ваш пример возвращаемого «xs: dateTime» полезен (чтобы помочь направить мое ошибочное понимание в правильном направлении!) –

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