От:
Сим
Дата: 03.06.04 12:40
Оценка:
Работаю с BizTalk. Нужно преобразовать одну XML схему в другую. Стандартными средствами бизтока мне не удалось сделать подобного преобразования, поэтому остается только ручной xslt. Т.к. в xslt я новичек, прошу помощи и гуру.
Итак, исходный файл:
<Source>
<Price>
<Date>1980</Date>
<Type>Type1</Type>
<Price>xxx</Price>
</Price>
<Price>
<Date>1980</Date>
<Type>Type2</Type>
<Price>yyy</Price>
</Price>
<Price>
<Date>2000</Date>
<Type>Type1</Type>
<Price>zzz</Price>
</Price>
<Price>
<Date>2000</Date>
<Type>Type2</Type>
<Price>ggg</Price>
</Price>
</ns0:Source>
На выходе нужно что-то вроде:
<Dest>
<Season>
<Date>1980</Date>
<Type>
<TypeName>Type1</TypeName>
<Price>xxx</Price>
</Type>
<Type>
<TypeName>Type2</TypeName>
<Price>yyy</Price>
</Type>
</Season>
<Season>
<Date>2000</Date>
<Type>
<TypeName>Type1</TypeName>
<Price>zzz</Price>
</Type>
<Type>
<TypeName>Type2</TypeName>
<Price>ggg</Price>
</Type>
</Season>
</Dest>
Проблема именно в группировеке данных по Date.
Re: Хитрое преобразование
От:
Сим
Дата: 04.06.04 09:38
Оценка:
В связи с немногочисленностью ответов, пришлось покопаться в XSLT самому.
Если кому интересно, вот что получилось:
<!-- Copy all tree -->
<xsl:variable name="All">
<xsl:copy-of select="/"/>
</xsl:variable>
<!-- Get all dates -->
<xsl:variable name="Dates">
<xsl:for-each select="Price">
<Date><xsl:value-of select="./Date"/></Date>
</xsl:for-each>
</xsl:variable>
<!-- Sort Dates -->
<xsl:variable name="SortedDates">
<xsl:for-each select="msxsl:node-set($Dates)/Date">
<xsl:sort select="."/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<!-- eliminate duplicaates -->
<xsl:variable name="UniqueDates">
<xsl:for-each select="msxsl:node-set($SortedDates)/Date">
<xsl:variable name="here" select="position()"/>
<xsl:if test="$here=1 or ../Date[position() < $here][1] != .">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($UniqueDates)/Date">
<xsl:variable name="cd">
<xsl:value-of select="." />
</xsl:variable>
<Season>
<Date><xsl:value-of select="$cd" /></Date>
<xsl:for-each select="msxsl:node-set($All)//Price[Date=$cd]">
<Type>
<PriceValue><xsl:value-of select="./PriceValue" /></PriceValue>
<TypeValue><xsl:value-of select="./Type" /></TypeValue>
</Type>
</xsl:for-each>
</Season>
</xsl:for-each>
Однако я думаю что можно было сделать и покрасивше
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить