0

我在 BizTalk 2009 中有一张地图,它将一些数据转换为 XML 文档以发送到另一个系统。目标模式包括一些具有xml:lang属性的元素。BizTalk 将这些生成为ns1:lang. 目标系统要求使用前缀xml

下面是一个简化的示例来展示 BizTalk 正在做什么:

sample.xsd

<xs:schema targetNamespace="http://example.com/"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="common.xsd"
             namespace="http://www.w3.org/XML/1998/namespace" />
  <xs:element name="example">
    <xs:complexType>
      <xs:attribute ref="xml:lang" />
    </xs:complexType>
  </xs:element>
</xs:schema>

common.xsd

<xs:schema xmlns:xml="http://www.w3.org/XML/1998/namespace"
           targetNamespace="http://www.w3.org/XML/1998/namespace"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:attribute name="lang" type="xs:language" />
</xs:schema>

地图输出示例

<ns0:example xmlns:ns0="http://example.com/"
             xmlns:ns1="http://www.w3.org/XML/1998/namespace"
             ns1:lang="en-US" />

有没有办法说服 BizTalk 使用xml前缀?

4

3 回答 3

4

据我所知,没有内置的方法可以实现这一点。

但是,我可以看到两种解决方案:

使用自定义 XML 样式表

如果您在地图上单击鼠标右键并仔细查看生成的 xsl 样式表,您将看到如下 XML 命名空间声明:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://www.w3.org/XML/1998/namespace"
                ...
                >
...
<xsl:attribute name="ns1:lang">
...

这是 BizTalk 映射器的默认行为,您对此无能为力。但是,如果您继续提取生成的 XSLT 并将其用作地图的后端,则可以更改此声明以匹配预期结果。

  • 首先,将样式表复制到项目的位置。
  • 将此样式表作为文件包含在 BizTalk 项目中
  • 更新样式表,使名称空间声明和匹配的属性前缀正确。

生成的 xsl 样式表如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xml="http://www.w3.org/XML/1998/namespace"
                ...
                >
...
<xsl:attribute name="xml:lang">
...

现在您可以使用此自定义样式表作为地图的后端。

  • 在 Visual Studio 中,打开地图。
  • 单击 BizTalk 设计器界面中空白区域的任意位置。
  • 在地图属性中,找到自定义 XSL 路径并指定自定义样式表的位置。

自定义 BizTalk 映射器 XSL 路径

使用自定义管道组件

您所追求的是该消息对于您的目标收件人是正确的。因此,想法是更改有问题的命名空间前缀,作为在 BizTalk 外部发送消息的一部分。转换发生在发送管道的处理过程中。

Nic Barden已经在博客中提供了一些关于此的源代码。您可以使用他的示例作为执行命名空间前缀替换的基础,而不是替换命名空间本身。

我强烈建议您查看他撰写的有关开发流式管道组件的整个系列文章。Nic 对编写健壮的企业级管道组件所需的一切进行了广泛而透彻的描述。

于 2011-01-03T10:52:41.457 回答
1

更简单的方法是在架构定义的开头添加命名空间声明,就像这样。

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xml="http://www.w3.org/XML/1998/namespace">
  <xs:import schemaLocation="xml.xsd" namespace="http://www.w3.org/XML/1998/namespace" />
于 2015-04-14T03:56:35.647 回答
0

除了 Maxime 的建议之外,还有我发现的其他可能性:

忽略它,希望供应商的API接受它。

我认为这行不通。当我测试地图时,BizTalk 给了我这个错误:

Output validation error: Prefix 'ns1' cannot be mapped to namespace name reserved for "xml" or "xmlns".

你好,BizTalk!?你是决定使用ns1的人。不要向我抱怨它!

使用基于 XSL 的脚本 functoid 来强制输出。

这是基于我在 BizTalk 论坛上收到的建议。它要求我们捏造输出模式以使用一个虚拟属性,该属性被functoid替换为 xml:lang 属性。

添加搜索/替换表达式

采用调用映射的编排,并在其后添加一个表达式,该表达式将接收我们发送给供应商的 XML,并通过搜索/替换正则表达式运行它以修复命名空间前缀。

于 2011-01-03T20:17:35.073 回答