2017-01-17 122 views
0

我有兩個輸入CSV文件,一個爲會員和一個用於他們看起來像下面 enter image description here的BizTalk XSLT映射

會員XML看起來像

<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看起來像

<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> 
效益

這兩個輸入都有EmployeeID字段。我需要與他們的利益

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 

這是我的地圖 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 
12,BENEFIT,MEA,001,0100189 
12,BENEFIT,DEN,002,0100189 
,,,, 
,,,, 
,,,, 
,,,, 

下面XSLT輸出映射

<?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分組的,它只是需要一點更多地控制BizTalk不允許通過標準映射設計器的for-each(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中做了更多的工作SQL實際上通過它合併一些數據和/或頁面),或者在C#中編寫自定義組件來處理它們比XSLT引擎最終能夠更有效地合併它們。

+0

謝謝丹。我對XSLT映射很陌生。從我當前的映射中,我應該刪除輸入和輸出模式之間的所有鏈接,並使用XSLT代碼。正如您所說,源代碼是Oracle數據庫的視圖,並且成員記錄有近2000條記錄,優點是12000條記錄。 – trx

+0

如果使用自定義c#組件。可以在映射中使用它嗎? – trx

+0

我會避免完全爲該卷的地圖。 XSLT不會很好地擴展,地圖將使用大量的內存。你應該尋找更好的方法來在SQL中準備你的數據,或者使用諸如'XmlReader'之類的流式管道組件來處理它。 –