2017-01-17 9 views
0

私は、2つの入力CSVファイルのメンバーのための1つ、彼らは給付XMLはのBizTalk XSLTマッピング

<Root xmlns="http://TestTwoInput.BenefitSchema"> 
<Record xmlns=""> 
    <EmployeeID>12</EmployeeID> 
    <BenefitText>BENEFIT</BenefitText> 
    <BCode>MEA</BCode> 
    <ELR>001</ELR> 
    <Control>0100189</Control> 
    </Record> 
<Record xmlns=""> 
    <EmployeeID>12</EmployeeID> 
    <BenefitText>BENEFIT</BenefitText> 
    <BCode>DEN</BCode> 
    <ELR>002</ELR> 
    <Control>0100189</Control> 
    </Record> 
<Record xmlns=""> 
    <EmployeeID>14</EmployeeID> 
    <BenefitText>BENEFIT</BenefitText> 
    <BCode>DEN</BCode> 
    <ELR>002</ELR> 
    <Control>0100189</Control> 
    </Record> 
<Record xmlns=""> 
    <EmployeeID>14</EmployeeID> 
    <BenefitText>BENEFIT</BenefitText> 
    <BCode>MEA</BCode> 
    <ELR>001</ELR> 
    <Control>0100189</Control> 
    </Record> 
<Record xmlns=""> 
    <EmployeeID>14</EmployeeID> 
    <BenefitText>BENEFIT</BenefitText> 
    <BCode>MEA</BCode> 
    <ELR>001</ELR> 
    <Control>0100189</Control> 
    </Record> 
<Record xmlns=""> 
    <EmployeeID>14</EmployeeID> 
    <BenefitText>BENEFIT</BenefitText> 
    <BCode>DEN</BCode> 
    <ELR>002</ELR> 
    <Control>0100189</Control> 
    </Record> 
    </Root> 
のように見えます
<Root xmlns="http://TestTwoInput.MemberSchema"> 
    <Record xmlns=""> 
    <EmployeeID>12</EmployeeID> 
    <MemberText>MEMBER</MemberText> 
    <SPID>007609952</SPID> 
    <MPID>007609952</MPID> 
    <SAID>12</SAID> 
    <ACode>05</ACode> 
    </Record> 
    <Record xmlns=""> 
    <EmployeeID>14</EmployeeID> 
    <MemberText>MEMBER</MemberText> 
    <SPID>004482352</SPID> 
    <MPID>004482352</MPID> 
    <SAID>14</SAID> 
    <ACode>05</ACode> 
    </Record> 
    </Root> 

状部材XMLが見え enter image description here

下回るように見える利益のための1つを持っています

両方の入力にEmployeeIDフィールドがあります。私は、これは私のマップ enter image description here ある

12,MEMBER,007609952,007609952,12,05 
12,BENEFIT,MEA,001,0100189 
12,BENEFIT,DEN,002,0100189 
14,MEMBER,004482352,004482352,14,05 
14,BENEFIT,DEN,002,0100189 
14,BENEFIT,MEA,001,0100189 
14,BENEFIT,MEA,001,0100189 
14,BENEFIT,DEN,002,0100189 

彼らの利益にそれぞれのメンバーのように一つの出力にして、両方のファイルをマップする必要があります。しかし、これはマッピング

ためのXSLT以下

12,MEMBER,007609952,007609952,12,05 
12,BENEFIT,MEA,001,0100189 
12,BENEFIT,DEN,002,0100189 
,,,, 
,,,, 
,,,, 
,,,, 
14,MEMBER,004482352,004482352,14,05 
12,BENEFIT,MEA,001,0100189 
12,BENEFIT,DEN,002,0100189 
,,,, 
,,,, 
,,,, 
,,,, 

のような出力がスローされます

<?xml version="1.0" encoding="UTF-16"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s1 s0 s2 userCSharp" version="1.0" xmlns:s1="http://TestTwoInput.BenefitSchema" xmlns:ns0="http://TestTwoInput.OutputSchema" xmlns:s0="http://TestTwoInput.MemberSchema" xmlns:s2="http://schemas.microsoft.com/BizTalk/2003/aggschema" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp"> 
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> 
<xsl:template match="/"> 
<xsl:apply-templates select="/s2:Root" /> 
</xsl:template> 
<xsl:template match="/s2:Root"> 
<ns0:Root> 
    <xsl:for-each select="InputMessagePart_0/s0:Root/Record"> 
    <Record> 
     <Member> 
     <EID> 
      <xsl:value-of select="EmployeeID/text()" /> 
     </EID> 
     <Text> 
      <xsl:value-of select="MemberText/text()" /> 
     </Text> 
     <SPID> 
      <xsl:value-of select="SPID/text()" /> 
     </SPID> 
     <MPID> 
      <xsl:value-of select="MPID/text()" /> 
     </MPID> 
     <SIAD> 
      <xsl:value-of select="SAID/text()" /> 
     </SIAD> 
     <ACode> 
      <xsl:value-of select="ACode/text()" /> 
     </ACode> 
     </Member> 
     <xsl:for-each select="../../../InputMessagePart_1/s1:Root/Record"> 
     <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(EmployeeID/text()) , string(../../../InputMessagePart_0/s0:Root/Record/EmployeeID/text()))" /> 
     <xsl:variable name="var:v3" select="string(EmployeeID/text())" /> 
     <xsl:variable name="var:v4" select="string(../../../InputMessagePart_0/s0:Root/Record/EmployeeID/text())" /> 
     <xsl:variable name="var:v5" select="userCSharp:LogicalEq($var:v3 , $var:v4)" /> 
     <Benefit> 
      <xsl:if test="string($var:v1)='true'"> 
      <xsl:variable name="var:v2" select="EmployeeID/text()" /> 
      <ID> 
       <xsl:value-of select="$var:v2" /> 
      </ID> 
      </xsl:if> 
      <xsl:if test="string($var:v5)='true'"> 
      <xsl:variable name="var:v6" select="BenefitText/text()" /> 
      <Text> 
       <xsl:value-of select="$var:v6" /> 
      </Text> 
      </xsl:if> 
      <xsl:if test="string($var:v5)='true'"> 
      <xsl:variable name="var:v7" select="BCode/text()" /> 
      <BCode> 
       <xsl:value-of select="$var:v7" /> 
      </BCode> 
      </xsl:if> 
      <xsl:if test="string($var:v5)='true'"> 
      <xsl:variable name="var:v8" select="ELR/text()" /> 
      <ELR> 
       <xsl:value-of select="$var:v8" /> 
      </ELR> 
      </xsl:if> 
      <xsl:if test="string($var:v5)='true'"> 
      <xsl:variable name="var:v9" select="Control/text()" /> 
      <Control> 
       <xsl:value-of select="$var:v9" /> 
      </Control> 
      </xsl:if> 
     </Benefit> 
     </xsl:for-each> 
    </Record> 
    </xsl:for-each> 
    </ns0:Root> 
</xsl:template> 
<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[ 
public bool LogicalEq(string val1, string val2) 
{ 
bool ret = false; 
double d1 = 0; 
double d2 = 0; 
if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2)) 
{ 
    ret = d1 == d2; 
} 
else 
{ 
    ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0; 
} 
return ret; 
} 

public bool IsNumeric(string val) 
{ 
if (val == null) 
{ 
    return false; 
} 
double d = 0; 
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d); 
} 

public bool IsNumeric(string val, ref double d) 
{ 
if (val == null) 
{ 
    return false; 
} 
return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d); 
} 


]]></msxsl:script> 
</xsl:stylesheet> 

XSLTを使用して出力を達成する方法がわかりません。これに関する助けがあれば幸いです。

+1

あなたは、この質問を複数の異なる文章で繰り返し投稿しているようです。 XSLTの問題として援助が必要な場合は、あなたのソース__XML__(例:BizTalkを通したネイティブフラットファイル)とあなたの期待される出力__XML__をあなたの試みたXSLT(ここやその他の投稿に含まれているようです) 。彼らが建設的でないなら、戻って、これと同様の質問を削除してください... –

+0

@DanFieldここに投稿する前に前の質問を削除しました。入力したXMLで質問を編集しました。これで助けてください。 – trx

答えて

1

だから、掲載され、あなたの入力メッセージは、それがこのようになるaggschema形式でのように見えると思いますかなりものではありません。

<Root xmlns="http://schemas.microsoft.com/BizTalk/2003/aggschema"> 
    <InputMessagePart_0 xmlns=""> 
    <Root xmlns="http://TestTwoInput.MemberSchema"> 
     <Record xmlns=""> 
     <EmployeeID>12</EmployeeID> 
     <MemberText>MEMBER</MemberText> 
     <SPID>007609952</SPID> 
     <MPID>007609952</MPID> 
     <SAID>12</SAID> 
     <ACode>05</ACode> 
     </Record> 
     <Record xmlns=""> 
     <EmployeeID>14</EmployeeID> 
     <MemberText>MEMBER</MemberText> 
     <SPID>004482352</SPID> 
     <MPID>004482352</MPID> 
     <SAID>14</SAID> 
     <ACode>05</ACode> 
     </Record> 
    </Root> 
    </InputMessagePart_0> 
    <InputMessagePart_1 xmlns=""> 
    <Root xmlns="http://TestTwoInput.BenefitSchema"> 
     <Record xmlns=""> 
     <EmployeeID>12</EmployeeID> 
     <BenefitText>BENEFIT</BenefitText> 
     <BCode>MEA</BCode> 
     <ELR>001</ELR> 
     <Control>0100189</Control> 
     </Record> 
     <Record xmlns=""> 
     <EmployeeID>12</EmployeeID> 
     <BenefitText>BENEFIT</BenefitText> 
     <BCode>DEN</BCode> 
     <ELR>002</ELR> 
     <Control>0100189</Control> 
     </Record> 
     <Record xmlns=""> 
     <EmployeeID>14</EmployeeID> 
     <BenefitText>BENEFIT</BenefitText> 
     <BCode>DEN</BCode> 
     <ELR>002</ELR> 
     <Control>0100189</Control> 
     </Record> 
     <Record xmlns=""> 
     <EmployeeID>14</EmployeeID> 
     <BenefitText>BENEFIT</BenefitText> 
     <BCode>MEA</BCode> 
     <ELR>001</ELR> 
     <Control>0100189</Control> 
     </Record> 
     <Record xmlns=""> 
     <EmployeeID>14</EmployeeID> 
     <BenefitText>BENEFIT</BenefitText> 
     <BCode>MEA</BCode> 
     <ELR>001</ELR> 
     <Control>0100189</Control> 
     </Record> 
     <Record xmlns=""> 
     <EmployeeID>14</EmployeeID> 
     <BenefitText>BENEFIT</BenefitText> 
     <BCode>DEN</BCode> 
     <ELR>002</ELR> 
     <Control>0100189</Control> 
     </Record> 
    </Root> 
    </InputMessagePart_1> 
</Root> 

このシナリオは本当に厳しくMuenchianグループ化を必要としない、それは少しだけを必要としますfor-each(BizTalkのループ機能)を制御し、BizTalkでは標準のマッピングデザイナを使用できません。出力XSLTを見ると、for-eachループがネストされている方法と、EmployeeIDノード間の等価性をテストしようとしている点で、非官能的なことがあることがわかります。ここではカスタムXSLTは、見て適切にネストされた(とBizTalkの生成や不要な変数を削除する)必要があります方法は次のとおりです。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s1 s0 s2 userCSharp" version="1.0" xmlns:s1="http://TestTwoInput.BenefitSchema" xmlns:ns0="http://TestTwoInput.OutputSchema" xmlns:s0="http://TestTwoInput.MemberSchema" xmlns:s2="http://schemas.microsoft.com/BizTalk/2003/aggschema" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp"> 
    <xsl:output omit-xml-declaration="yes" indent="yes" method="xml" version="1.0" /> 
    <xsl:template match="/"> 
    <xsl:apply-templates select="/s2:Root" /> 
    </xsl:template> 
    <xsl:template match="/s2:Root"> 
    <ns0:Root> 
     <xsl:for-each select="InputMessagePart_0/s0:Root/Record">   
     <Record> 
      <Member> 
      <EID> 
       <xsl:value-of select="EmployeeID/text()" /> 
      </EID> 
      <Text> 
       <xsl:value-of select="MemberText/text()" /> 
      </Text> 
      <SPID> 
       <xsl:value-of select="SPID/text()" /> 
      </SPID> 
      <MPID> 
       <xsl:value-of select="MPID/text()" /> 
      </MPID> 
      <SIAD> 
       <xsl:value-of select="SAID/text()" /> 
      </SIAD> 
      <ACode> 
       <xsl:value-of select="ACode/text()" /> 
      </ACode> 
      </Member> 
      <xsl:variable name="empID" select="EmployeeID" /> 
      <xsl:for-each select="../../../InputMessagePart_1/s1:Root/Record[EmployeeID = $empID]"> 
      <Benefit>    
       <ID> 
       <xsl:value-of select="EmployeeID/text()" /> 
       </ID> 
       <Text> 
       <xsl:value-of select="BenefitText/text()" /> 
       </Text> 
       <BCode> 
       <xsl:value-of select="BCode/text()" /> 
       </BCode> 
       <ELR> 
       <xsl:value-of select="ELR/text()" /> 
       </ELR> 
       <Control> 
       <xsl:value-of select="Control/text()" /> 
       </Control> 
      </Benefit> 
      </xsl:for-each> 
     </Record> 
     </xsl:for-each> 
    </ns0:Root> 
    </xsl:template> 
</xsl:stylesheet> 

これはあなたに次のような出力が得られます。

<ns0:Root xmlns:ns0="http://TestTwoInput.OutputSchema"> 
    <Record> 
     <Member> 
     <EID>12</EID> 
     <Text>MEMBER</Text> 
     <SPID>007609952</SPID> 
     <MPID>007609952</MPID> 
     <SIAD>12</SIAD> 
     <ACode>05</ACode> 
     </Member> 
     <Benefit> 
     <ID>12</ID> 
     <Text>BENEFIT</Text> 
     <BCode>MEA</BCode> 
     <ELR>001</ELR> 
     <Control>0100189</Control> 
     </Benefit> 
     <Benefit> 
     <ID>12</ID> 
     <Text>BENEFIT</Text> 
     <BCode>DEN</BCode> 
     <ELR>002</ELR> 
     <Control>0100189</Control> 
     </Benefit> 
    </Record> 
    <Record> 
     <Member> 
     <EID>14</EID> 
     <Text>MEMBER</Text> 
     <SPID>004482352</SPID> 
     <MPID>004482352</MPID> 
     <SIAD>14</SIAD> 
     <ACode>05</ACode> 
     </Member> 
     <Benefit> 
     <ID>14</ID> 
     <Text>BENEFIT</Text> 
     <BCode>DEN</BCode> 
     <ELR>002</ELR> 
     <Control>0100189</Control> 
     </Benefit> 
     <Benefit> 
     <ID>14</ID> 
     <Text>BENEFIT</Text> 
     <BCode>MEA</BCode> 
     <ELR>001</ELR> 
     <Control>0100189</Control> 
     </Benefit> 
     <Benefit> 
     <ID>14</ID> 
     <Text>BENEFIT</Text> 
     <BCode>MEA</BCode> 
     <ELR>001</ELR> 
     <Control>0100189</Control> 
     </Benefit> 
     <Benefit> 
     <ID>14</ID> 
     <Text>BENEFIT</Text> 
     <BCode>DEN</BCode> 
     <ELR>002</ELR> 
     <Control>0100189</Control> 
     </Benefit> 
    </Record> 
</ns0:Root> 

はここでプレーするために上記のXSLTRANSFORMです:http://xsltransform.net/3NSSEvs

xsl:key(Muenchianグルーピング)を使用するとパフォーマンスが向上する可能性があります。大規模なドキュメントの結果セットでこれを使用する場合は、いくつかの調査を行います。しかし、あなたの書類があなたがここに典型的に送ったもののように見えたら、あなたは大丈夫でしょう。正直言って、もしそれらがかなり大きくなるならば、私はXSLTを使ってすべてを解決しようとするよりも、ソースでリファクタリングすることをアドバイスします - 可能であればフラットファイルを生成するプロセスを制限します(おそらく、実際にデータの一部をマージしたり、ページを通したりするSQL)、またはC#でカスタムコンポーネントを作成して、XSLTエンジンより効率的にマージする処理を行うことができます。

+0

Danに感謝します。私はXSLTマッピングには非常に新しいです。現在のマップから、入力と出力のスキーマ間のリンクをすべて削除し、XSLTコードを使用するだけです。あなたが言ったように、ソースはOracle Databaseからのビューであり、メンバー・レコードは2000レコード近くあり、メリットは12000レコードです。 – trx

+0

カスタムC#コンポーネントを使用している場合。これをマッピングに使用できますか? – trx

+0

私は完全にそのボリュームのマップを避けるだろう。 XSLTはそこではうまくスケールされません、マップはメモリの負荷を使用します。あなたは、SQLでデータを準備する、または 'XmlReader'のようなものを使ってストリーミングパイプラインコンポーネントでデータを処理する、より良い方法を模索すべきです。 –

関連する問題