BizTalk 将 XML 消息的一部分提取到另一个

BizTalk extract part of XML message to another

我有一个 XML 文件:

<soapenv:Envelope>
   <soapenv:Header/>
   <soapenv:Body>
      <doc:Request>
        ... some XML text as flat text or like XML ...
      </doc:Request>
   </soapenv:Body>
</soapenv:Envelope>

我需要在 <doc:Request> </doc:Request> 之间保存文本到新消息并将其保存为 XML 文件。

在编排中,在消息分配形状中使用 xpath()

msgExtracted = xpath(msgSoap, "/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='Request']");

在自定义管道组件中,将 pInMsg.BodyPart.GetOriginalDataStream() 加载到 XmlReader,然后 ReadToFollowing("Request", "namespace_for_doc_here"); 节点,然后使用 reader.ReadSubtree() 获取它并 return 它作为留言。

最后,由于很有可能您正在使用基于 WCF 的适配器,您可以在适配器设置中指定消息的 Body XPath - 或者只是告诉适配器包含SOAP 主体而不是信封。

在传入的消息架构中创建一个可区分的字段(确保您正在复制架构的最佳实践)指向 doc:Request(我假设doc 名称空间已在消息中注册)。然后创建一个 Message Assignment Shape 并简单地实例化一个所需类型的新消息(当然你需要一个描述 doc:Request 的新模式)

newMessageType.body = incomingMessage.Request;

如果确实需要,您可以通过 xpath 执行此操作,但请注意,每次执行 xpath 查询时,整个消息都会加载到内存中。如果您的消息很大或者您有大量的 xpath 查询,这可能会导致巨大的开销。此外,如果您的消息很复杂,您的 xpath 可能难以阅读。一个可区分的字段总是很容易阅读,如果你更新你的模式,你不需要改变编排。我强烈建议不要使用 xpath!

备注 如果您在此处的任务的唯一目的是从消息中获取该位并将其保存为您在此处声明的 XML 文件,则您甚至不需要编排。您可以将映射添加到接收端口,该映射转换为新的消息类型,并让发送端口订阅输出 doc:Request 消息,该消息通过文件适配器简单保存。

xpath 和可分辨字段将起作用。但是简单的方法不是将带有 soapenv 命名空间的 xml 内容结构定义为信封模式,然后让 xmldisassmbler 完成剩下的事情吗?