Biztalk在XSLT转换中爆炸

时间:2009-09-21 07:42:03

标签: xslt biztalk transformation

我正在将XML接收到BizTalk中。一部分是元素,值是由逗号分隔的ID

<Stores>15,34</Stores>

我需要将其转换为

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

我需要做的是用逗号分解值,取每个值并从数据库中获取值(15 - &gt; Store 1,34 - &gt; Store 2)。

如何在xslt中进行爆炸,如何从数据库中获取每个爆炸值的值。我已经在db中有过程,只需要知道如何调用它。

3 个答案:

答案 0 :(得分:2)

BizTalk Mapper不支持XSLT 2.0(请参阅MSDN文档http://msdn.microsoft.com/en-us/library/aa559261(BTS.10).aspx),因此如果要使用映射器,则需要使用EXSLT扩展。

Richard Hallgren撰写了一篇很棒的文章here,介绍了如何在BizTalk Mapper中使用EXSLT。

另外一个想法是关于替代解决方案。目前尚不清楚您是否绝对必须逐个调用数据库 - 是否可以进行单个调用?

可以为存储过程提供分隔字符串作为参数,然后使用函数来破坏此字符串。我在下面列出了这样一个函数的例子,例子是一个表函数。您将能够在网络上找到许多其他实现。

使用table函数,您可以在商店查找过程中加入此功能。

如果这符合您的需求,它应该快得多,因为您现在只执行一次数据库命中,并且可以执行设置操作以取回您的商店列表。

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

答案 1 :(得分:2)

这是一个与爆炸有关的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>

David Hall的解决方案似乎包含一个指针,指示如何使用XSLT扩展函数从XSLT调用该数据库。

答案 2 :(得分:1)

我假设您知道如何编写整体转换,但需要帮助对包含商店编号的字符串进行标记化。

如果您正在使用XSLT 2.0,请查看tokenize()函数的定义。这会将字符串值拆分为指定的分隔符,允许您执行此转换。在XSLT 1中,您可以查看EXSLT正则表达式扩展函数。