用于对多条记录进行分组和排序的 BizTalk XSLT 映射

BizTalk XSLT Mapping For Grouping and Sorting with Multiple Records

输入消息:

输入文件在详细信息中有三个记录,顺序为“Member”、“Product”和“Dependent”,在每个 Record 中都有一个公共字段,即“Identifier”。出于某种原因,我们得到了每个成员和产品循环到一个细节中,每个依赖项循环到单独的细节中 ..................................................... ...................................

    <ns0:Root xmlns:ns0="Test">
  <Detail>
    <Member>
      <Name>Jerry</Name>
      <Address>Miami</Address>
      <PhoneNumber>7008084201</PhoneNumber>
      <Identifier>225692067</Identifier>
    </Member>
    <Product>
      <Name>Phone</Name>
      <Type>Personal</Type>
      <Serial>000000111111</Serial>
      <Identifier>225692067</Identifier>
    </Product>
  </Detail>
  <Detail>
    <Dependent>
      <DependentName>Tom</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>7228084302</DependentPhoneNumber>
      <Identifier>225692067</Identifier>
    </Dependent>
  </Detail>
  <Detail>
    <Dependent>
      <DependentName>Tom1</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>8228084302</DependentPhoneNumber>
      <Identifier>225692067</Identifier>
    </Dependent>
  </Detail>
  <Detail>
    <Dependent>
      <DependentName>Tom2</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>9228084302</DependentPhoneNumber>
      <Identifier>225692067</Identifier>
    </Dependent>
  </Detail>
  <Detail>
    <Member>
      <Name>John</Name>
      <Address>Kansas</Address>
      <PhoneNumber>5007684306</PhoneNumber>
      <Identifier>699039521</Identifier>
    </Member>
    <Product>
      <Name>Xbox</Name>
      <Type>Personal</Type>
      <Serial>000000222222</Serial>
      <Identifier>699039521</Identifier>
    </Product>
  </Detail>
  <Detail>
    <Member>
      <Name>Larry</Name>
      <Address>Newjersey</Address>
      <PhoneNumber>6004567307</PhoneNumber>
      <Identifier>230903815</Identifier>
    </Member>
    <Product>
      <Name>Iphone</Name>
      <Type>Personal</Type>
      <Serial>0000003333333</Serial>
      <Identifier>230903815</Identifier>
    </Product>
  </Detail>
  <Detail>
    <Dependent>
      <DependentName>Luis</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>7897684302</DependentPhoneNumber>
      <Identifier>230903815</Identifier>
    </Dependent>
  </Detail>
  <Detail>
    <Dependent>
      <DependentName>LuisMead</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>7229876302</DependentPhoneNumber>
      <Identifier>230903815</Identifier>
    </Dependent>
  </Detail>
</ns0:Root>

预期输出 XML:

输出文件与输入文件类似,但顺序是“成员”、“依赖”和“产品”。公共字段“标识符”在这种情况下很常见 also.The 想法是让详细信息在“成员”、“依赖”和“产品”订单上循环。 ..................................................... ...................................

    <ns0:Root xmlns:ns0="Test">
  <Detail>
    <Member>
      <Name>Jerry</Name>
      <Address>Miami</Address>
      <PhoneNumber>7008084201</PhoneNumber>
      <Identifier>225692067</Identifier>
    </Member>

    <Dependent>
      <DependentName>Tom</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>7228084302</DependentPhoneNumber>
      <Identifier>225692067</Identifier>
    </Dependent>
    <Dependent>
      <DependentName>Tom1</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>8228084302</DependentPhoneNumber>
      <Identifier>225692067</Identifier>
    </Dependent>
    <Dependent>
      <DependentName>Tom2</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>9228084302</DependentPhoneNumber>
      <Identifier>225692067</Identifier>
    </Dependent>
    <Product>
      <Name>Phone</Name>
      <Type>Personal</Type>
      <Serial>000000111111</Serial>
      <Identifier>225692067</Identifier>
    </Product>
  </Detail>
  <Detail>
    <Member>
      <Name>John</Name>
      <Address>Kansas</Address>
      <PhoneNumber>5007684306</PhoneNumber>
      <Identifier>699039521</Identifier>
    </Member>
    <Product>
      <Name>Xbox</Name>
      <Type>Personal</Type>
      <Serial>000000222222</Serial>
      <Identifier>699039521</Identifier>
    </Product>
  </Detail>
  <Detail>
    <Member>
      <Name>Larry</Name>
      <Address>Newjersey</Address>
      <PhoneNumber>6004567307</PhoneNumber>
      <Identifier>230903815</Identifier>
    </Member>

    <Dependent>
      <DependentName>Luis</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>7897684302</DependentPhoneNumber>
      <Identifier>230903815</Identifier>
    </Dependent>
    <Dependent>
      <DependentName>LuisMead</DependentName>
      <DependentAddress>Miami</DependentAddress>
      <DependentPhoneNumber>7229876302</DependentPhoneNumber>
      <Identifier>230903815</Identifier>
    </Dependent>
    <Product>
      <Name>Iphone</Name>
      <Type>Personal</Type>
      <Serial>0000003333333</Serial>
      <Identifier>230903815</Identifier>
    </Product>
  </Detail>

</ns0:Root>

需要有关为此编写 XSLT 1.0 代码的建议。

您可以在 XSLT-1.0 中使用 Muenchian Grouping 执行此操作。在 Whosebug 上搜索它,你会发现很多例子。应用它创建了以下答案:

  • 使用节点 Member|Dependent|Product 创建一个 xsl:key,使用其 Identifier 元素值作为键
  • 创建一个 sortingOrder 变量,该变量提供用于对内部 xsl:for-each
  • 中的条目进行排序的索引
  • 用模板匹配并复制根节点/ns0:Root
  • 遍历 xsl:for-eachDetail 个元素的所有子元素。该表达式应用 Muenchian 分组 方法
  • 创建一个Detail元素,并循环遍历前面xsl:for-each的结果,按照当前元素名称在sortingOrder[=中出现的索引排序37=]变量。复制其内容。元素排序的方法采取了from this SO answer: "Sorting XML in XSLT based on a list of values".

样式表可能如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="Test">
<xsl:output indent="yes"/>
<xsl:key name="id" match="Member|Dependent|Product" use="Identifier" />   
<xsl:variable name="sortingOrder" select="'Member,Dependent,Product'" />

<xsl:template match="/ns0:Root">
    <xsl:copy>
        <xsl:for-each select="Detail/*[generate-id() = generate-id(key('id',Identifier)[1])]">
            <Detail>
                <xsl:for-each select="key('id',Identifier)">
                    <xsl:sort data-type="number" select="string-length(substring-before($sortingOrder,local-name()))" />
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </Detail>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

输出应该符合要求。