可以通过直接在映射源 (.btm) 文件中修改 mapsource 元素的属性来修改 BizTalk Mapper 的某些默认行为。
优化值映射 Functoid 代码生成
当 Mapper 生成 XSLT 代码以调用 值映射 functoid 时,将使用变量来存储结果。 可以使用 OptimizeValueMapping 标志优化值映射 functoid,以便仅当if
语句计算为True
时生成变量。 例如,将 OptimizeValueMapping 设置为 “否”
<xsl:variable name="var:v5" select="ScriptNS0:FormatMessage(…)" />
<xsl:if test="string($var:v4)='true'">
<xsl:variable name="var:v6" select="string($var:v5)" />
<ns0:text>
<xsl:value-of select="$var:v6" />
</ns0:text>
</xsl:if>
可以通过将 值映射 functoid 调用移动到语句正文 if
来优化此代码,确保仅在需要调用时才发生。 将 OptimizeValueMapping 设置为 “是 ”将生成以下代码:
<xsl:if test="string($var:v4)='true'">
<xsl:variable name="var:v5" select="ScriptNS0:FormatMessage(…)" />
<xsl:variable name="var:v6" select="string($var:v5)" />
<ns0:text>
<xsl:value-of select="$var:v6" />
</ns0:text>
</xsl:if>
如果将映射源 (.btm) 文件中 mapsource 元素的 OptimizeValueMapping 属性设置为“是”,则 Mapper 会自动执行此优化,如下所示:
<mapsource Name="BizTalk Map" BizTalkServerMapperTool_Version="2.0" Version="2" XRange="100" YRange="420" OmitXmlDeclaration="Yes" TreatElementsAsRecords="No" OptimizeValueMapping="Yes" GenerateDefaultFixedNodes="Yes" CopyPIs="No" method="xml" xmlVersion="1.0" IgnoreNamespacesForLinks="Yes">
容纳大规模架构的方案
当映射器使用具有非常大的实例占用的架构时,该架构具有非常复杂的结构和/或递归节点,测试映射、验证映射或编译映射可能需要很长时间,或者更糟的情况下,会导致“内存不足”错误。 这可能发生在小型复杂架构以及大型架构中。
复杂架构的问题是,由于映射器必须以递归方式加载整个架构树,以便查找那些连接有链接或设置了 Value 属性的节点。 通过将 .btm 文件中 mapsource 元素的 GenerateDefaultFixedNodes 标志设置为“否”来缓解此问题,如下所示:
<mapsource Name="BizTalk Map" BizTalkServerMapperTool_Version="2.0" Version="2" XRange="100" YRange="420" OmitXmlDeclaration="Yes" TreatElementsAsRecords="No" OptimizeValueMapping="No" GenerateDefaultFixedNodes="No" CopyPIs="No" method="xml" xmlVersion="1.0" IgnoreNamespacesForLinks="Yes">
使用此设置时,Mapper 不需要创建与目标架构的每个架构节点关联的内部编译器节点。 编译器仅考虑链接节点。 这大大减少了内存消耗,并在执行“测试映射”或“验证映射”作、编译映射或保存地图时加快了进程速度。
但是,当 GenerateDefaultFixedNodes 标志设置为 “否”时,目标架构中设置的默认字段值不会保留在映射生成的实例中。 当目标实例中需要这些值时,这是一个问题。 若要规避这种情况,必须在地图中再次显式设置所需的值。 可以将 GenerateDefaultFixedNodes 标志设置为 RequiredDefaults,这意味着将考虑所有必需的节点。 这包括链接的节点、具有默认值的节点、属性 MinOccurs 设置为大于或等于 1 的节点,以及其父节点是必需的节点。
注释
将 GenerateDefaultFixedNodes 设置为 No 或 RequiredDefaults 后,应测试映射并验证输出是否与 GenerateDefaultFixedNodes 设置为其默认值 “是”时相同,其中所有节点都由编译器考虑在内。
使用循环、条件和值映射参照功能管理 for-each 的用法
使用 循环、条件 或 值映射 functoid 时, 在编译的映射中会生成一个 xsl:for-each
语句。 如果目标架构的子字段最大出现次数未加限制,则 xsl:for-each
语句将放置在子字段上。 如果子字段没有无限的最大出现次数,则 xsl:for-each
语句将放在父字段中。
但是,由于语句的位置 xsl:for-each
会影响映射结果,因此你可能希望将 xsl:for-each
语句置于目标架构的子字段,而不考虑子字段的最大出现次数是否设置为 1。
可以通过修改 map (.btm) 文件中 TreatElementsAsRecords 属性的值来控制语句的位置xsl:for-each
,如下所示:
<mapsource Name="BizTalk Map" BizTalkServerMapperTool_Version="2.0" Version="2" XRange="100" YRange="420" OmitXmlDeclaration="Yes" TreatElementsAsRecords="No" OptimizeValueMapping="No" GenerateDefaultFixedNodes="Yes" CopyPIs="No" method="xml" xmlVersion="1.0" IgnoreNamespacesForLinks="Yes">
当此属性设置为“是”时,无论子字段的最大出现次数是否设置为 1,该xsl:for-each
语句都会置于目标架构的子字段。
映射重复序列组时保留顺序
XSD 架构中的序列组不提供循环上下文,因为它们未在消息实例中表示。 如果没有对序列组循环的可能性,Mapper 编译器不会生成适当的 XSLT 来维护段顺序。 因此,输入实例中存在的相对上下文丢失,这使得依赖于相对上下文的进一步处理无法利用输出实例。
将重复序列映射到另一个重复序列时,可以使用 PreserveSequenceOrder 标志来维护记录顺序。 默认情况下,标志的值设置为 “否 ”,以保留在早期 BizTalk Server 版本中创建的现有映射的功能,其中该标志不存在。 在新创建的映射中,标志将存在,并且其值被设置为 否。 若要维护段顺序,必须将 .btm 文件中的值显式设置为 “是 ”,如下所示:
<mapsource Name="BizTalk Map" BizTalkServerMapperTool_Version="2.0" Version="2" XRange="100" YRange="420" OmitXmlDeclaration="Yes" TreatElementsAsRecords="No" OptimizeValueMapping="No" GenerateDefaultFixedNodes="Yes" PreserveSequenceOrder="Yes" CopyPIs="No" method="xml" xmlVersion="1.0" IgnoreNamespacesForLinks="Yes">
下面是一个示例输入实例:
<Name>Person1</Name>
<Gender>Male</Gender>
<Address>Bellevue</Address>
<Name>Person2</Name>
<Gender>Female</Gender>
<Address>Redmond</Address>
将 PreserveSequenceOrder 标志设置为 “否”后,输出实例将如下所示:
<Name>Person1</Name>
<Name>Person2</Name>
<Gender>Male</Gender>
<Gender>Female</Gender>
<Address>Bellevue</Address>
<Address>Redmond</Address>
将 PreserveSequenceOrder 标志设置为 “是”后,输出实例将如下所示:
<Name>Person1</Name>
<Gender>Male</Gender>
<Address>Bellevue</Address>
<Name>Person2</Name>
<Gender>Female</Gender>
<Address>Redmond</Address>