下面是输入消息:
输入:
Record Name : Member
Fields: Company Name , Person Name , State , Country , Amount , CombinedState
这是我的输入XML:
<ns0:Root xmlns:ns0="Test">
<Detail>
<Member>
<CompanyName>XYZ</CompanyName>
<PersonName>Ashwin</PersonName>
<State>KS</State>
<Country>USA</Country>
<Amount>1000</Amount>
<CombinedState>Yes</CombinedState>
</Member>
<Member>
<CompanyName>XYZ</CompanyName>
<PersonName>Lingam</PersonName>
<State>AZ</State>
<Country>USA</Country>
<Amount>1001</Amount>
<CombinedState>Yes</CombinedState>
</Member>
<Member>
<CompanyName>XYZ</CompanyName>
<PersonName>John</PersonName>
<State>KS</State>
<Country>USA</Country>
<Amount>1000</Amount>
<CombinedState>Yes</CombinedState>
</Member>
<Member>
<CompanyName>ABC</CompanyName>
<PersonName>Larry</PersonName>
<State>IL</State>
<Country>USA</Country>
<Amount>1000</Amount>
<CombinedState>No</CombinedState>
</Member>
<Member>
<CompanyName>ABC</CompanyName>
<PersonName>Lingam</PersonName>
<State>NJ</State>
<Country>USA</Country>
<Amount>1001</Amount>
<CombinedState>Yes</CombinedState>
</Member>
<Member>
<CompanyName>Bright</CompanyName>
<PersonName>John</PersonName>
<State>FL</State>
<Country>USA</Country>
<Amount>1000</Amount>
<CombinedState>Yes</CombinedState>
</Member>
</Detail>
</ns0:Root>
输出应如下所示:
<ns0:Root xmlns:ns0="http://BizTalk_Server_Project1.Output">
<T>
<SeqNo>1</SeqNo>
<Name>Something</Name>
</T>
<Group>
<A>
<CompanyName>XYZ</CompanyName>
<Segment>A</Segment>
</A>
<B>
<CompanyName>XYZ</CompanyName>
<PersonName>Ashwin</PersonName>
<Country>USA</Country>
<State>KS</State>
<Amount>1000</Amount>
</B>
<B>
<CompanyName>XYZ</CompanyName>
<PersonName>Lingam</PersonName>
<Country>USA</Country>
<State>AZ</State>
<Amount>1001</Amount>
</B>
<B>
<CompanyName>XYZ</CompanyName>
<PersonName>John</PersonName>
<Country>USA</Country>
<State>KS</State>
<Amount>1000</Amount>
</B>
<C>
<TotalAmount>3001</TotalAmount>
</C>
<K>
<State>KS</State>
<TotAmount>2000</TotAmount>
</K>
<K>
<State>AZ</State>
<TotAmount>1001</TotAmount>
</K>
</Group>
<Group>
<A>
<CompanyName>ABC</CompanyName>
<Segment>A</Segment>
</A>
<B>
<CompanyName>ABC</CompanyName>
<PersonName>Larry</PersonName>
<Country>USA</Country>
<State>IL</State>
<Amount>1000</Amount>
</B>
<B>
<CompanyName>ABC</CompanyName>
<PersonName>Lingam</PersonName>
<Country>USA</Country>
<State>NJ</State>
<Amount>1001</Amount>
</B>
<C>
<TotalAmount>2001</TotalAmount>
</C>
<K>
<State>NJ</State>
<TotAmount>1001</TotAmount>
</K>
</Group>
<Group>
<A>
<CompanyName>Bright</CompanyName>
<Segment>A</Segment>
</A>
<B>
<CompanyName>Bright</CompanyName>
<PersonName>John</PersonName>
<Country>USA</Country>
<State>AZ</State>
<Amount>1000</Amount>
</B>
<C>
<TotalAmount>1000</TotalAmount>
</C>
<K>
<State>AZ</State>
<TotAmount>1000</TotAmount>
</K>
</Group>
</ns0:Root>
我尝试过的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 s0 userCSharp" version="1.0" xmlns:s0="Test" xmlns:ns0="http://BizTalk_Server_Project1.Output" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:key name="group1" match ="Member" use ="CompanyName"/>
<xsl:key name="group2" match ="Member" use ="concat(CompanyName,'|',PersonName)"/>
<xsl:key name="group3" match ="Member" use ="concat(CompanyName,'|',State)"/>
<xsl:template match="/">
<xsl:apply-templates select="/s0:Root" />
</xsl:template>
<xsl:template match="/s0:Root">
<xsl:variable name="var:v1" select="userCSharp:StringConcat("1")" />
<xsl:variable name="var:v2" select="userCSharp:StringConcat("1234567")" />
<ns0:Root>
<T>
<SeqNo>
<xsl:value-of select="$var:v1" />
</SeqNo>
<Name>
<xsl:value-of select="$var:v2" />
</Name>
</T>
<xsl:for-each select="Detail/Member[generate-id(.)=generate-id(key('group1',CompanyName))]">
<Group>
<A>
<CompanyName>
<xsl:value-of select="CompanyName/text()" />
</CompanyName>
<Segment>
<xsl:value-of select="'A'" />
</Segment>
</A>
<xsl:for-each select="Detail/Member[generate-id(.)=generate-id(key('group2',concat(CompanyName,'|',PersonName)))]"> <!--2nd key-->
<B>
<CompanyName>
<xsl:value-of select="CompanyName/text()" />
</CompanyName>
<PersonName>
<xsl:value-of select="PersonName/text()" />
</PersonName>
<Country>
<xsl:value-of select="Country/text()" />
</Country>
<State>
<xsl:value-of select="State/text()" />
</State>
<Amount>
<xsl:value-of select="Amount/text()" />
</Amount>
</B>
</xsl:for-each>
<c> <!--Uses 1st key-->
<TotalAmount>
<xsl:value-of select="sum(key('group1', CompanyName)/Amount)" />
</TotalAmount>
</c>
<xsl:for-each select="Detail/Member[generate-id(.)=generate-id(key('group3',concat(CompanyName,'|',State)))]"> <!--3rd Key-->
<k>
<State>
<xsl:value-of select="State/text()" />
</State>
<TotAmount>
<xsl:value-of select="sum(key('group3', concat(CompanyName,'|',State))/Amount)" />
</TotAmount>
</k>
</xsl:for-each>
</Group>
</xsl:for-each>
</ns0:Root>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public string StringConcat(string param0)
{
return param0;
}
]]></msxsl:script>
</xsl:stylesheet>
要求是:
所需输出的结构如下:
Record Name : T
Field Name :SeqNo , Value :1 ( HardCoded )
Field Name : Name , Value : Something(Hardcoded)
Record Name:
Group:
Child Record Name: A (This Child Record has max occurs 1 and Occurs only 1 per Company Name)
Req: For each company A record will be created only once
Field Name: CompanyName , Value: From the input field Company Name
Field Name: Segment , Value: A (HardCoded)
Child Record Name : B ( This Child record Max occurs unbounded and groups all member under Each company Name )
Example and requirement : Input Member have company name “xyz” and total number of member having company name xyz is “3” so the B record will occur 3 times
Field Name: Company Name , Value: From the input field Company Name
Field Name: Person Name , Value : From the input field Person Name
Field Name: Country , Value : From the input field Country
Field Name: State , value : From the input field State
Field Name : Amount , Value : from the input field Amount
Child Record Name : C (This Child Record has max occurs 1 )
Field Name : Total Amount , Value : This will be the cumulative of the amounts under each company
Example : If Company name XYZ have 3 member each of 1000 then the cumulative will be 3000
Child Record Name : K(This child Record has max occurs unbounded )
Field Name : State , Value : From the input field State
Field Name : TotAmount , Value : Below is the requirement
要求:
输入中的字段“ CombinedState”将告诉您是“是”还是“否”,如果为“是”,那么它将为每个状态创建一个记录并总计每个状态的金额。
示例:
对于XYZ公司,有3个成员,它们的状态分别为KS,AZ和KS,因此我们必须创建两个K记录,即,一个用于KS,一个用于AZ,由于XYZ有2个成员,因此我们需要对KS的数量求和KS状态,
问题:
组中的每个Record使用不同的键,我写的XSLT对于B和K记录不起作用。
答案 0 :(得分:1)
我调试了您的XSLT。
您的主要错误是没有将密钥从外部xsl:for-each
馈送到内部xsl:for-each
。因此,更改
<xsl:for-each select="Detail/Member[generate-id(.)=generate-id(key('group2',concat(CompanyName,'|',PersonName)))]">
到
<xsl:for-each select="key('group1',CompanyName)[generate-id(.)=generate-id(key('group2',concat(CompanyName,'|',PersonName)))]">
成功了。第三个xsl:for-each
也是如此。
这是新的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<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" xmlns:s0="Test" xmlns:ns0="http://BizTalk_Server_Project1.Output" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp" exclude-result-prefixes="msxsl var s0 userCSharp" version="1.0">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0"/>
<xsl:key name="group1" match="Member" use="CompanyName"/>
<xsl:key name="group2" match="Member" use="concat(CompanyName,'|',PersonName)"/>
<xsl:key name="group3" match="Member" use="concat(CompanyName,'|',State)"/>
<xsl:template match="/">
<xsl:apply-templates select="/s0:Root"/>
</xsl:template>
<xsl:template match="/s0:Root">
<xsl:variable name="var:v1" select="'"1"'"/>
<xsl:variable name="var:v2" select="'"1234567"'"/>
<ns0:Root>
<T>
<SeqNo>
<xsl:value-of select="$var:v1"/>
</SeqNo>
<Name>
<xsl:value-of select="$var:v2"/>
</Name>
</T>
<xsl:for-each select="Detail/Member[generate-id(.)=generate-id(key('group1',CompanyName))]">
<Group>
<A>
<CompanyName>
<xsl:value-of select="CompanyName/text()"/>
</CompanyName>
<Segment>
<xsl:value-of select="'A'"/>
</Segment>
</A>
<xsl:for-each select="key('group1',CompanyName)[generate-id(.)=generate-id(key('group2',concat(CompanyName,'|',PersonName)))]">
<!--2nd key-->
<B>
<CompanyName>
<xsl:value-of select="CompanyName/text()"/>
</CompanyName>
<PersonName>
<xsl:value-of select="PersonName/text()"/>
</PersonName>
<Country>
<xsl:value-of select="Country/text()"/>
</Country>
<State>
<xsl:value-of select="State/text()"/>
</State>
<Amount>
<xsl:value-of select="Amount/text()"/>
</Amount>
</B>
</xsl:for-each>
<C>
<!--Uses 1st key-->
<TotalAmount>
<xsl:value-of select="sum(key('group1', CompanyName)/Amount)"/>
</TotalAmount>
</C>
<xsl:for-each select="key('group1',CompanyName)[generate-id(.)=generate-id(key('group3',concat(CompanyName,'|',State)))]">
<!--3rd Key-->
<K>
<State>
<xsl:value-of select="State/text()"/>
</State>
<TotAmount>
<xsl:value-of select="sum(key('group3', concat(CompanyName,'|',State))/Amount)"/>
</TotAmount>
</K>
</xsl:for-each>
</Group>
</xsl:for-each>
</ns0:Root>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
public string StringConcat(string param0)
{
return param0;
}
]]></msxsl:script>
</xsl:stylesheet>
输出与您给定的XML并不完全匹配,但是我想您的版本是错误的,因为上述XSLT的输出确实满足了您的要求。