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

时间:2019-01-24 17:49:16

标签: xslt biztalk

输入消息:

输入文件的明细内有三个记录,顺序为“成员”,“产品”和“从属”,在每个记录中都有一个公共字段,即“标识符”。由于某些原因,我们变得像每个成员和产品循环成一个细节,每个从属循环成单独的细节 ................................................... .....................

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

预期的OutPut XML:

输出文件也类似于输入文件,但顺序为“成员”,“从属”和“产品”。在这种情况下,通用字段“标识符”也是通用的。其想法是使“细节”按“成员”,“从属”和“产品”顺序循环。 ................................................... ....................................

    <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代码的建议。

1 个答案:

答案 0 :(得分:1)

您可以在XSLT-1.0中使用 Muenchian分组来执行此操作。在StackOverflow上搜索它,您将找到很多示例。应用它会产生以下答案:

  • 使用其xsl:key元素值作为键,使用节点Member|Dependent|Product创建一个Identifier
  • 创建一个 sortingOrder 变量,该变量提供用于对内部xsl:for-each
  • 中的条目进行排序的索引
  • 使用模板匹配并复制根节点/ns0:Root
  • 遍历Detailxsl:for-each元素的所有子元素。该表达式应用了 Muenchian分组方法
  • 创建一个Detail元素,并循环遍历前一个xsl:for-each的结果,该结果按 sortingOrder 变量中当前元素名称的出现索引进行排序。复制其内容。排序元素的方法采用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>

输出应为所需。