join - 如何使用 BizTalk 映射器通过将 2 个不同的重复节点连接到 1 个重复节点来进行映射
问题描述
问题是我需要遍历一个重复节点,但还要从基于 LineId 匹配的兄弟重复节点中提取信息。如果这是一个数据库,我会将每个重复节点等同于一个表,并希望根据匹配的 id 输出两个表的连接。
我首先将 Root/Shipments/Shipment/Containers/Container 循环到 Document/Header/Detail 并且这似乎有效,因为我想为来自源的每个 Container 创建 1 条记录作为目标中的 1 Detail 记录。但是当我从 Root/Shipments/Shipment/Details/Detail 映射字段时,我只从映射的第一条记录中获取数据,而不是从具有匹配 LineId 的记录中获取数据。然后我尝试将 Root/Shipments/Shipment/Details/Detail 添加到循环中,并有条件地抑制 LineId 在节点之间不匹配但不起作用的 Document/Detail。因此,我尝试在具有相同抑制条件的 Detail 上添加第二个循环,但这也不起作用。然后我想我会尝试使用 XSLT 模板来“查找”基于 LineId 作为输入的 Root/Shipments/Shipment/Details/Detail 中的数据,但它从未返回任何数据(它始终为空)。此外,要在字段级别分别获取每个字段,我需要搜索 X 次,我需要映射的每个字段 1 次,而不是每条记录 1 次,所以这似乎也效率低下。
我的 XSLT 知识有限。如果可能的话,我更愿意将 Mapping 与脚本 functoid 一起使用,而不是纯 XSLT。性能也将是一个问题,因为我需要做的文件数量在这个项目中非常高。我在下面给出的示例是我需要处理更多字段的一个非常精简的版本,并且源文件在层次结构中具有更多层。
实现我需要做的最好方法是什么?
源文件:
<Root>
<Shipments>
<Shipment>
<ShipId>1</ShipId>
<Details>
<Detail>
<LineId>1</LineId>
<RequestedQty>10</RequestedQty>
<Sku>347</Sku>
<Status>C</Status>
</Detail>
<Detail>
<LineId>2</LineId>
<RequestedQty>5</RequestedQty>
<Sku>125</Sku>
<Status>P</Status>
</Detail>
<Detail>
<LineId>3</LineId>
<RequestedQty>8</RequestedQty>
<Sku>337</Sku>
<Status>O</Status>
</Detail>
<Detail>
<LineId>4</LineId>
<RequestedQty>12</RequestedQty>
<Sku>7438</Sku>
<Status>C</Status>
</Detail>
</Details>
<Containers>
<Container>
<ContainerId>1</ContainerId>
<Details>
<Detail>
<LineId>1</LineId>
<Lot>103</Lot>
<ShipQty>10</ShipQty>
</Detail>
<Detail>
<LineId>2</LineId>
<Lot>102</Lot>
<ShipQty>3</ShipQty>
</Detail>
</Details>
<TrackingNUmber>Z934793498923984</TrackingNUmber>
</Container>
<Container>
<ContainerId>2</ContainerId>
<Details>
<Detail>
<LineId>4</LineId>
<Lot>101</Lot>
<ShipQty>10</ShipQty>
</Detail>
<Detail>
<LineId>4</LineId>
<Lot>105</Lot>
<ShipQty>2</ShipQty>
</Detail>
</Detail>
</Details>
<TrackingNUmber>Z531365161663161</TrackingNUmber>
</Container>
</Containers>
</Shipment>
</Shipments>
</Root>
进入:
<Document>
<Header>
<ShipId>1</ShipId>
<Detail>
<ContainerId>1</ContainerId>
<LineId>1</LineId>
<Lot>103</Lot>
<ShipQty>10</ShipQty>
<RequestedQty>10</RequestedQty>
<Sku>347</Sku>
<Status>C</Status>
<TrackingNUmber>Z934793498923984</TrackingNUmber>
</Detail>
<Detail>
<ContainerId>1</ContainerId>
<LineId>2</LineId>
<Lot>102</Lot>
<ShipQty>3</ShipQty>
<RequestedQty>5</RequestedQty>
<Sku>125</Sku>
<Status>P</Status>
<TrackingNUmber>Z934793498923984</TrackingNUmber>
</Detail>
<Detail>
<ContainerId>2</ContainerId>
<LineId>4</LineId>
<Lot>101</Lot>
<ShipQty>10</ShipQty>
<RequestedQty>12</RequestedQty>
<Sku>7438</Sku>
<Status>C</Status>
<TrackingNUmber>Z531365161663161</TrackingNUmber>
</Detail>
<Detail>
<ContainerId>2</ContainerId>
<LineId>4</LineId>
<Lot>105</Lot>
<ShipQty>2</ShipQty>
<RequestedQty>12</RequestedQty>
<Sku>7438</Sku>
<Status>C</Status>
<TrackingNUmber>Z531365161663161</TrackingNUmber>
</Detail>
</Header>
</Document>
解决方案
我不确定它是不是最好的解决方案,但我有一些东西可能会让你继续前进。这个想法是使用脚本函数在目标文档中创建 Detail 元素。
鉴于您有很多元素,我建议您使用以下方法来正确命名:
“验证地图”以获取 xslt。复制 Detail-element 及其内容。
删除所有指向 Detail 元素的直接链接。
在源 Container/Details/Detail 和目标 Detail 之间添加循环 functoid。
添加一个脚本functoid,将它连接到目标Detail。选择 Inline XSLT 并粘贴您在步骤 2 中复制的代码。
测试地图,以验证它的大部分是否有效(尽管 Shipment/Details/Detail 仍然是错误的)
修改脚本functoid中的xslt。您需要一个变量来指向与当前行对应的 Shipment/Details/Detail 元素。
根据当前 LineId 设置变量:
<xsl:variable name="CurrentShipmentDetail" select="../../../../Details/Detail[LineId=current()/LineId]"/>
- 修改元素,以便从变量中进行选择
前:
<RequestedQty>
<xsl:value-of select="../../../../Details/Detail/RequestedQty/text()" />
</RequestedQty>
后:
<RequestedQty>
<xsl:value-of select="$CurrentShipmentDetail/RequestedQty/text()" />
</RequestedQty>
完整地图:
以及完整的 xslt 代码:
<Detail>
<ContainerId>
<xsl:value-of select="../../ContainerId/text()" />
</ContainerId>
<LineId>
<xsl:value-of select="LineId/text()" />
</LineId>
<Lot>
<xsl:value-of select="Lot/text()" />
</Lot>
<ShipQty>
<xsl:value-of select="ShipQty/text()" />
</ShipQty>
<xsl:variable name="CurrentShipmentDetail" select="../../../../Details/Detail[LineId=current()/LineId]"/>
<RequestedQty>
<xsl:value-of select="$CurrentShipmentDetail/RequestedQty/text()" />
</RequestedQty>
<Sku>
<xsl:value-of select="$CurrentShipmentDetail/Sku/text()" />
</Sku>
<Status>
<xsl:value-of select="$CurrentShipmentDetail/Status/text()" />
</Status>
<TrackingNUmber>
<xsl:value-of select="../../TrackingNUmber/text()" />
</TrackingNUmber>
</Detail>
推荐阅读
- python - 如何从一系列随机字符创建数据集以分割它们
- javascript - ASP.NET 多人游戏
- html - 多个文本 CSS 动画不会在指定时间开始
- amazon-web-services - 如何使用 Cloudfront 将裸域重定向到 www?
- python - 使用 DictReader 读取 csv 文件可能有哪些优点和缺点?
- ios - 在 UITableViewCell 内显示 youtube 视频缩略图和标题
- batch-file - UAC 提示后恢复批处理文件
- python - 动态sql查询(字符串模板)
- excel - 元素未从数组中获取值
- java - 在不使用中断的情况下正确终止 Java 可调用线程?