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:
Вот как обойти этот баг:
! Обратите внимание, что 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 на это надо было бы уже давно поставить.
Если в 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() <= $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 на это надо было бы уже давно поставить.
Комментарии
Отправить комментарий