首页 > 解决方案 > 嵌套条件循环(一对多)

问题描述

输入中有两个 xml,InputMessagePart_0 有多个位置 id,InputMessagePart_1 有多个 ItemMaster,然后我需要创建一个输出,对于每个位置 id,我都需要有 Item Master。

我已经编写了 Xslt,它没有在 InputMessagePart_0(Record) 级别上循环并且它只采用第一个 Location id ,

XSlT1.0:

<?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 s2 s1" version="1.0" xmlns:s0="http://Test.ItemMaster" xmlns:s2="http://schemas.microsoft.com/BizTalk/2003/aggschema" xmlns:s1="http://Test.Lookup" xmlns:ns0="http://Test.Out">
  <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_1/s0:Root/ItemMaster">

        <xsl:variable name="var:v1" select="../../../InputMessagePart_0/s1:Root/Record/LocationId" />
        <xsl:variable name="var:v2" select="ItemId" />
        <xsl:variable name="var:v3" select="ItemName" />
        <xsl:variable name="var:v4" select="Quantity" />
        <Detail>
          <LocationId>
            <xsl:value-of select="$var:v1" />
          </LocationId>
          <ItemId>
            <xsl:value-of select="$var:v2" />
          </ItemId>
          <ItemName>
            <xsl:value-of select="$var:v3" />
          </ItemName>
          <Qty>
            <xsl:value-of select="$var:v4" />
          </Qty>
        </Detail>
      </xsl:for-each>
    </ns0:Root>
  </xsl:template>
</xsl:stylesheet>

输入 XML:

<ns0:Root xmlns:ns0="http://schemas.microsoft.com/BizTalk/2003/aggschema">
    <InputMessagePart_0>
        <ns0:Root xmlns:ns0="http://Test.Lookup">
  <Record>

    <LocationId>12</LocationId>
  </Record>
  <Record>

    <LocationId>13</LocationId>
  </Record>
  <Record>

    <LocationId>14</LocationId>
  </Record>
</ns0:Root>
    </InputMessagePart_0>
    <InputMessagePart_1>
        <ns0:Root xmlns:ns0="http://Test.ItemMaster">
  <ItemMaster>
    <ItemId>123</ItemId>
    <ItemName>Knife</ItemName>
    <Quantity>1</Quantity>
  </ItemMaster>
  <ItemMaster>
    <ItemId>1234</ItemId>
    <ItemName>Knife1</ItemName>
    <Quantity>1</Quantity>
  </ItemMaster>
  <ItemMaster>
    <ItemId>1235</ItemId>
    <ItemName>Knife3</ItemName>
    <Quantity>1</Quantity>
  </ItemMaster>
</ns0:Root>
    </InputMessagePart_1>
</ns0:Root>

当前输出:

<ns0:Root xmlns:ns0="http://Test.Out">
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
</ns0:Root>

期望的输出:

<ns0:Root xmlns:ns0="http://Test.Out">
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>13</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>13</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>13</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>14</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>14</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>14</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
</ns0:Root>



Desired OutPut : 

<ns0:Root xmlns:ns0="http://Test.Out">
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>12</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>13</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>13</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>13</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>14</LocationId>
        <ItemId>123</ItemId>
        <ItemName>Knife</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>14</LocationId>
        <ItemId>1234</ItemId>
        <ItemName>Knife1</ItemName>
        <Qty>1</Qty>
    </Detail>
    <Detail>
        <LocationId>14</LocationId>
        <ItemId>1235</ItemId>
        <ItemName>Knife3</ItemName>
        <Qty>1</Qty>
    </Detail>
</ns0:Root>

标签: xsltbiztalk

解决方案


您需要有一个xsl:for-each(或xsl:apply-templates)来获取Record带有位置的元素。(这xsl:for-each将包含当前xsl:for-eachItemMaster

试试这个 XSLT

<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 s2 s1" version="1.0" xmlns:s0="http://Test.ItemMaster" xmlns:s2="http://schemas.microsoft.com/BizTalk/2003/aggschema" xmlns:s1="http://Test.Lookup" xmlns:ns0="http://Test.Out">
  <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" version="1.0" />

  <xsl:template match="/s2:Root">
    <ns0:Root>
      <xsl:for-each select="InputMessagePart_0/s1:Root/Record">
        <xsl:variable name="var:v1" select="LocationId" /> 
        <xsl:for-each select="../../../InputMessagePart_1/s0:Root/ItemMaster">
          <Detail>
            <LocationId>
              <xsl:value-of select="$var:v1" />
            </LocationId>
            <ItemId>
              <xsl:value-of select="ItemId" />
            </ItemId>
            <ItemName>
              <xsl:value-of select="ItemName" />
            </ItemName>
            <Qty>
              <xsl:value-of select="Quantity" />
            </Qty>
          </Detail>
        </xsl:for-each>
      </xsl:for-each>
    </ns0:Root>
  </xsl:template>
</xsl:stylesheet>

请注意,此处的模板匹配/并不是必需的,因为 XSLT 的内置模板可以做同样的事情。


推荐阅读