Biztalk взорваться в XSLT-преобразованиях - PullRequest
2 голосов
/ 21 сентября 2009

Я получаю XML в BizTalk. Одна часть является элементом, а значение - это идентификаторы, разделенные запятой

<Stores>15,34</Stores>

Мне нужно преобразовать это в

<Stores>
    <Store>Store 1</Store>
    <Store>Store 4</Store>
</Stores>

Что мне нужно сделать, так это разобрать значение запятой, взять каждое значение и получить значение из базы данных (15 -> Магазин 1, 34 -> Магазин 2).

Как сделать разнесение в xslt, как получить значение из базы данных для каждого разнесенного значения. У меня уже есть процедура в БД для этого, просто нужно знать, как ее вызвать.

Ответы [ 3 ]

2 голосов
/ 23 сентября 2009

BizTalk Mapper не поддерживает XSLT 2.0 (см. Документацию MSDN http://msdn.microsoft.com/en-us/library/aa559261(BTS.10).aspx), поэтому вам нужно будет использовать расширения EXSLT, если вы хотите использовать маппер.

Здесь есть отличный пост здесь Ричарда Халлгрена, в котором рассказывается, как использовать EXSLT в BizTalk Mapper.

Еще одна мысль об альтернативном решении. Не ясно, нужно ли вам совершать вызовы из базы данных один за другим - сработает ли один вызов?

Можно предоставить хранимой процедуре строку с разделителями в качестве параметра и затем использовать функцию, чтобы разбить эту строку. Я включил пример такой функции ниже, примером является табличная функция. Вы сможете найти множество других реализаций в Интернете.

С помощью табличной функции вы можете присоединиться к этой процедуре поиска в магазине.

Если это соответствует вашим потребностям, это должно быть намного быстрее, так как теперь вы выполняете всего одно попадание в базу данных и можете выполнять операции над множествами, чтобы получить обратно список магазинов.

CREATE function fn_ParseCSVString
(   
    @INPUTCSV varchar(MAX)
)
RETURNS @TBL TABLE 
( 
    COL1 INT
)
AS
BEGIN
DECLARE @NUM_STR NVARCHAR(MAX)
SET @NUM_STR = @INPUTCSV

SET @NUM_STR = REPLACE(@NUM_STR,' ','')     
-- this will trim any intermediate spaces

WHILE LEN(@NUM_STR) >= 0
BEGIN 

DECLARE @@SUBSTR VARCHAR(100) 
IF CHARINDEX(',',@NUM_STR,0) <> 0   
BEGIN   
SET @@SUBSTR = SUBSTRING(@NUM_STR,0,CHARINDEX(',',@NUM_STR,0))   
INSERT INTO @TBL VALUES(@@SUBSTR)  
END 
ELSE   
BEGIN   
INSERT INTO @TBL VALUES(@NUM_STR)   
BREAK   
END  

SET @@SUBSTR = @@SUBSTR + ',' 

SET @NUM_STR = SUBSTRING(@NUM_STR, CHARINDEX(',',@NUM_STR,0) + 1, LEN(@NUM_STR)) 

END
RETURN
END
2 голосов
/ 23 сентября 2009

Вот XSLT 1.0-совместимое решение, которое делает разнесение:

<!-- straightforward -->
<xsl:template match="Stores">
  <xsl:copy>
    <xsl:call-template name="explode">
      <xsl:with-param name="str" select="text()" />
    </xsl:call-template>
  </xsl:copy>
</xsl:template>

<!-- string processing through recursion -->
<xsl:template name="explode">
  <xsl:param name="str" select="''" />

  <xsl:variable name="temp" select="concat($str, ',')" />
  <xsl:variable name="head" select="substring-before($temp, ',')" />
  <xsl:variable name="tail" select="substring-after($temp, ',')" />

  <xsl:if test="$head != ''">
    <Store>
      <xsl:value-of select="$head" />
    </Store>
    <xsl:call-template name="explode">
      <xsl:with-param name="str" select="$tail" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Выход для <Stores>15,34</Stores> будет:

<Stores>
  <Store>Store 15</Store>
  <Store>Store 34</Store>
</Stores>

Решение Дэвида Холла, похоже, содержит указатель на то, какиспользовать функцию расширения XSLT для вызова этой базы данных из XSLT.

1 голос
/ 22 сентября 2009

Я предполагаю, что вы знаете, как написать общее преобразование, но вам нужна помощь с токенизацией строки, содержащей номера магазинов.

Если вы используете XSLT 2.0, посмотрите определение функции tokenize (). Это разделит строковое значение в указанном разделителе, что позволит вам выполнить это преобразование. В XSLT 1 вы можете посмотреть на функции расширения регулярных выражений EXSLT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...