Тэги

Silverlight (36) WPF (10) IIS (7) Visual Studio (7) SharePoint (6) .Net Framework (5) ODP.NET (5) ASP.NET (4) C# (4) common (4) Network Settings (3) JavaScript (2) MS Office (2) Resharper (2) WCF (2) WEB (2) XPath (2) XSLT (2) ADO.NET (1) APEX (1) CMD (1) CSS (1) EF (1) HTML (1) Hardware bugs (1) Java (1) MS SQL (1) Oracle (1) PDF (1) Version Control (1) XAML (1)

воскресенье, 13 марта 2011 г.

XSLT и XPath баг в MSXML 4.0.

Нашел баг XSLT и XPath в MSXML 4. Видимо в версиях ниже он тоже есть.

Если в XSLT-переменную xsl:variable положить набор нод, полученный с помощью XPath выражения preceding-sibling, то набор строк (Node Set) в этой переменной будет храниться не в том порядке, в котором он представлен в XML.
Вроде, порядок нод будет обратный тогда.

При этом, если перебирать Node Set напрямую в xsl:for-each, без присвоения набора в переменную xsl:variable, то все будет работать правильно. Утверждать не стану, т.к. уже не помню точно, но вроде это так.

Получается в MSXML 4, preceding-sibling можно использовать только для получения количества элементов в наборе нод или для прямого перебора, но не для выборки элементов в переменную.

Проиллюстрирую баг кодом.
В следующей переменной FirstSecondThirdTables.Rows получим набор элементов ServiceRow, лежащих до ноды из переменной $FourthTable.Rows.First.
Но порядок элементов в ней будет не такой, какой он в XML:
<xsl:variable name="FirstSecondThirdTables.Rows" select="$FourthTable.Rows.First/preceding-sibling::ServiceRow"/>
Вот как обойти этот баг:
<!-- it3xl.ru: Сначала получим количество нужных нод лежащих до граничной ноды -->
<xsl:variable name="FirstSecondThirdTables.RowsCount" select="count($FourthTable.Rows.First/preceding-sibling::ServiceRow)"/>
<!-- it3xl.ru: Теперь применим стандартный фильтр по position(). -->
<xsl:variable name="FirstSecondThirdTables.Rows" select="ServiceRow[position() &lt;= $FirstSecondThirdTables.RowsCount]"/>


! Обратите внимание, что Visual Studio с 2005-й версии, да и MS SQL, уже давно используют MSXML 6, поэтому вы можете заметить баг только на промышленной среде.

Чтобы быстро проверить на этот баг в разработческой среде нужен скрипт, который выполняет XSLT преобразования именно через MSXML 4.
Я такой батничек или JS-скрипт затерял, поэтому MSDN вам в помощь для написания этого скрипта. Можно начать отсюда http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx.

Мой большой друг спросил меня по этому поводу: "Ребята из Рэдмонда опять что-то отчебучили?"
Хотел бы я там с ними тоже поотчебучивать :)
Вот только Service Pack на это надо было бы уже давно поставить.

Комментариев нет:

Отправить комментарий