XSLT 変換で Biztalk が爆発的に増加
-
12-09-2019 - |
質問
XML を BizTalk で受信しています。1 つの部分は要素であり、値はカンマで区切られた ID です。
<Stores>15,34</Stores>
これを次のように変換する必要があります
<Stores>
<Store>Store 1</Store>
<Store>Store 4</Store>
</Stores>
私がしなければならないことは、値をカンマで展開し、各値を取得してデータベースから値を取得することです(15 -> ストア 1、34 -> ストア 2)。
xslt で展開を行うにはどうすればよいですか。展開された値ごとにデータベースから値を取得するにはどうすればよいですか。そのためのプロシージャがすでにデータベースにあります。それを呼び出す方法を知る必要があるだけです。
解決
ここで爆発しない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拡張機能を使用するにはどのようにポインタが含まれているようだ。
他のヒント
BizTalk マッパーは XSLT 2.0 をサポートしていません (MSDN ドキュメントを参照) http://msdn.microsoft.com/en-us/library/aa559261(BTS.10).aspx) したがって、マッパーを使用したい場合は、EXSLT 拡張機能を使用する必要があります。
素晴らしい投稿があります ここ Richard Hallgren 著。BizTalk マッパー内で EXSLT を使用する方法について説明しています。
もう 1 つの考えは、代替ソリューションについてです。データベース呼び出しを必ず 1 つずつ実行する必要があるかどうかは明確ではありません。1 回の呼び出しだけで機能するのでしょうか?
ストアド プロシージャに区切り文字で区切られた文字列をパラメータとして指定し、関数を使用してこの文字列を分割することができます。以下にそのような関数の例を示します。例はテーブル関数です。Web 上では他にも多くの実装を見つけることができます。
テーブル関数を使用すると、ストア検索プロシージャでこれに対して結合できます。
これがニーズを満たしている場合は、データベース ヒットを 1 回実行するだけで、セット操作を実行して店舗のリストを取得できるため、はるかに高速になるはずです。
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
私はあなたが、全体的な変換が、店舗数を含む文字列のトークン化を支援する必要があるの書き方を知っていると仮定します。
あなたがXSLT 2.0を使用している場合は、、トークン化()関数の定義を見てみましょう。これは、この変換を実行することができ、指定された区切り文字で文字列値を分割します。 XSLT 1では、EXSLT正規表現の拡張機能を見ることができます。