映射定义从一个XML文档到另一个XML文档的转化。它用在一下三个地方:
1. 为了将特定贸易合作伙伴或者内部系统传入的特定消息转化为内部XML格式。这是通过在接受端 口或者双向接口的接收端设置映射完成的。
2. 将将要发送的内部XML格式的消息转化为贸易合作伙伴或者内部系统特定的格式。这是通过在发 送端口或者双向端口的发送端设置映射完成的。
3. 业务处理过程中需要转换。
映射器
可以在visual studio 2010 中使用biztalk映射工具开发映射,并且保存为biztalk特定的XML格式,但是当编译项目的时候,会将其编译为可扩展样式表语言转换(XSLT)。事实上,你甚至可以使用自己的XSLT解决使用映射工具不能解决的复杂的转换。但是只支持XSLT 1.0.
传入的文件可能是XML或者在接收管道被转化为XML,转化过程发生在接收端口执行映射之前。同样在发送端口,映射执行过程也发生在发送管道转化输出消息格式之前。这使映射器和XSLT对biztalk操作的所有文件都起作用。由于XSLT只能作用于XML,这提供了一种统一的良好而干净的方式处理biztalk中的文件转换。
当开发一个转换的时候,考虑到给定的源架构,你总是觉得映射的输入是有效的。这至少需要如下条件之一:
1. 在接收管道打开校验功能,这意味着要不你使用的是带有XML校验组件的自定义管道,要不就是 在拆分器上开启了校验功能。
2. 你相信发送系统和贸易伙伴发送的消息总是有效的,因此没有必要打开校验功能。这可能是基于 性能的考虑。这样做的缺点就是后续处理过程无法预知结果,并且出错的话很难解决。
无论是哪种方式,你的业务都必须决定怎么做。是应该打开校验在处理过程开始的时候就捕获错误,还是因为发送者比较可信或者你决定在错误出现的时候处理而关闭校验?作为转换的开发者,你需要知道进入的XML的状态。如果在某个点映射失败了,这可能会导致无法预料的行为,如下:
1. 编排可能会启动失败并被休眠,因为编排内部的逻辑是基于有效的输入。
2. 如果映射失败,进入的消息可能会被休眠。
3. 如果在发送管道校验你的XML,映射根据架构产生了无效的XML,校验将会失败,此时消息也会 被休眠,不会进行发送。
处理完这些之后,你就可以开始考虑怎样实现映射了。大多的映射是很简单的,你仅仅需要指定源中的哪个节点映射到目的架构中哪个节点。其中需要注意保证两者的数据类型和基数的匹配。如果两者的数据类型不同,你或许就麻烦了。通常说来,你讲一个类型映射到另一个限制更少的类型往往是安全的。比如将int映射到string类型。然而,其他的方式并不是如此的简单,你有三种选择:
1. 更改源架构中节点的数据类型或者为节点的值添加更加严格的限制。比如,可以使用正则表达式 控制字符串只包括数字。
2. 更改目标架构相关节点的数据类型。放宽限制可能会导致后续的业务处理出现问题。
3. 在映射里进行处理。架构完成并与贸易合作伙伴达成一致后,它们进行更改往往并不容易。所以, 你可能想在映射中解决这个问题。你可以使用functoids来处理。
如果源节点是可选的但是目的节点不是,就会出现问题。为了防止输入节点的缺失应该做些什么是值得考虑的事情。同样,你有三种选择:
1. 改变源架构的可选节点为必须节点。
2. 将目的架构中的相关节点改为可选节点。
3. 在映射里进行处理。你可能想在映射中处理。你可以使用functoids来处理这种场景。这可能是映 射了一个默认值,也肯能是抛出异常。
Functoids
biztalk提供的functoids可以在源值拷贝到目的节点之前进行一些预处理。这个处理过程可以做任何事情,比如将字符串转化大写、使用三角函数、进行数据库查询等。biztalk提供了很多种内置的functoids并进行了分类,其中类别有字符串、数学、逻辑判断、日期时间、转换(编码)、科学计数法、累计(聚合)、数据库、高级、第三方。
你可以使用内置的functoids构建代码块解决你大多的映射需求。然而有时你需要的功能内置functoids并没有提供。有时,你可能发现自己一遍又一遍的在映射中建了很多相同的functoids组合解决特定的问题。这是十分烦人的并使你的映射变得脏乱不堪。为了解决这个问题,你可以开发自己的functoids。开发自定义的functoids并不像听起来那样难,事实上,你会发现最困难的是创建一个漂亮的可以描述你的functoids的图标。
functoids被分为两大类:
1. 非累计或者通常的,它们暴露为带有参数或者没有参数并返回字符串的方法。
2. 累计的,它们暴露三个方法,第一个初始化,第二个传入所有参数,但三个获取最终的值。
当然,functoids可以分为另外两类:
1. 编译到程序集中的类并部署到GAC中。在运行时可以调用该类的一个或者多个方法完成你的功能。 这就是引用functoids。
2. 在运行时调用但不暴露方法的类,其输出一段包含在映射中的脚本。这个类型就是众所周知的内 联functoids;
在下面情况下你应该考虑开发内联functoids:
1. 你不担心你的代码作为纯文本被放入映射中(这允许其他人读取和修改)。
2. 你的functoids只依赖映射中可用的.NET的命名空间。
3. 你不想维护另外的程序集,需要时刻谨记将其添加到安装脚本里,将它部署到所有的biztalk服务 器等。
4. 你想为使用functoids的开发者提供调试使用该functoids的映射的能力。
5. 你开发了多于一个的functoids,并且他们需要共享变量。
下边情况下需要考虑开发引用functoids:
1. 将一个新的程序集部署到GAC并重启主机实例,所有的映射都不需要重新编译就可以使用这个 functoids。
2. 不想以明文方式暴露自己的业务逻辑代码。
3. functoids依赖映射中不可用的.NET命名空间.
事实上,你不必一定要选择内联或者应用的functoids,你可以开发你的functoids兼容两种类型(to be both),让映射的开发者决定使用哪种。