Oracle11g 在业务流程内手动构造消息

Oracle11g 在业务流程内手动构造消息,oracle11g,biztalk,biztalk-2010,Oracle11g,Biztalk,Biztalk 2010,情况是这样的。 我有一系列12个集成任务,每15分钟运行一次,其中大多数实际上是从oracle服务器读取一些内容并将其推送到web服务中。我已经为oracle和web服务创建了一个端口,并且创建了一个主业务流程,它每15分钟循环一次,并调用将执行其任务的其他业务流程 现在,我的问题是,这些业务流程不是由消息到达调用的,我需要构造一条消息,将其发送到oracle端口。看起来像这样的一个: <Select xmlns="http://Microsoft.LobServices.OracleDB

情况是这样的。 我有一系列12个集成任务,每15分钟运行一次,其中大多数实际上是从oracle服务器读取一些内容并将其推送到web服务中。我已经为oracle和web服务创建了一个端口,并且创建了一个主业务流程,它每15分钟循环一次,并调用将执行其任务的其他业务流程

现在,我的问题是,这些业务流程不是由消息到达调用的,我需要构造一条消息,将其发送到oracle端口。看起来像这样的一个:

<Select xmlns="http://Microsoft.LobServices.OracleDB/2007/03/HR/Table/EMPLOYEES">
    <COLUMN_NAMES>*</COLUMN_NAMES>
    <FILTER>DATE=somedate</FILTER>
</Select>

*
日期
我知道节点值将是什么,但我不知道如何构造消息,除了使用“魔术字符串”和连接字符串之外,我将使用LoadXml将这些字符串加载到xmlDoc中,然后将其分配给消息参数,出于许多原因,我非常希望避免这些参数(从将来更改名称空间开始)。是否有一种编排方法来创建“空白”消息,然后由我填写


也许问题很简单,我从林中看不到树,但我在网上看到的所有示例都是简化的(这意味着有人只是将一个现成的xml放在一个监视的文件夹中调用编排),对我没有帮助

您是否考虑过使用转换形状来创建要发送到ORACLE的模式实例

这是在消息分配形状中创建消息的一种替代方法。 如果您需要更多详细信息,请告诉我


HTH

创建一个静态助手函数,该函数返回一种XmlDocument类型。从指定形状中调用此函数

在helper函数中,您可以从配置文件或文本文件加载设置(名称空间等,甚至完整消息)


为了获得最佳实践,您应该将此配置存储在SSO中。如果您需要这方面的帮助,请告诉我。

我为一个类似的问题实现了一个解决方案:正如Hugh建议的那样,我使用从XmlDocument继承的帮助器

Xml模板类

using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Xml;

namespace Acme
{
    [Serializable]
    public class ResourceXmlDocument : XmlDocument
    {
        public ResourceXmlDocument(Type assemblyType, string resourceName, QueryValues queryValues)
        {
            try
            {
                Assembly callingAssembly = Assembly.GetAssembly(assemblyType);

                if (null == callingAssembly)
                {
                    throw new ResourceException("GetExecutingAssembly returned null");
                }

                Stream resourceStream = callingAssembly.GetManifestResourceStream(resourceName);

                Load(resourceStream);

                if (null == queryValues)
                {
                    throw new ResourceException("queryValues not initialized");
                }

                if (queryValues.Keys.Count < 1)
                {
                    throw new ResourceException("queryValues.Keys must have at least one value");
                }


                foreach (string querycondition in queryValues.Keys)
                {
                    XmlNode conditionNode = this.SelectSingleNode(querycondition);

                    if (null == conditionNode)
                    {
                        throw new ResourceException(string.Format(CultureInfo.InvariantCulture, "Condition: '{0}' did not return a XmlNode", querycondition));
                    }

                    XmlAttribute valueAttribute = conditionNode.Attributes["value"];

                    if (null == valueAttribute)
                    {
                        throw new ResourceException(string.Format(CultureInfo.InvariantCulture, "Condition: '{0}' with attribute 'value' did not return an XmlAttribute ", querycondition));
                    }

                    valueAttribute.Value = queryValues[querycondition];
                }
            }
            catch (Exception ex)
            {
                throw new ResourceException(ex.Message);
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Acme
{
    [Serializable]
    public class QueryValues : Dictionary<string, string>
    {
        public QueryValues()
        {
        }


        protected QueryValues(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }
    }
}
Xml模板

向项目中添加一个Xml doc MyTemplate.Xml,并将编译操作更改为
Embedded Resource
,以便ResorceXmlDocument可以通过反射加载它

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <SomeOtherNode>some (fixed) value</SomeOtherNode>
    <MyNodeName tablename="MyTableName" fieldname="MyFieldName" value="0" />
    <YetAnotherNode>
        <SubNode>Foo</SubNode>
    </YetAnotherNode>
</root>
我将
ResourceXmlDocument
QueryValue
保存在一个util库中,并从我需要的任何BizTalk项目中引用它。各种Xml模板文档嵌入到相应的BizTalk程序集中

按OP编辑:实际上,我实现这一点的唯一方法是在
ResourceXmlDocument
上实现
ISerializable
,并使用OuterXml的自定义序列化来持久化消息。库中的XmlDocument本身是不可序列化的。如果有其他方法,请随意编辑

[Serializable]
public class ResourceXmlDocument : XmlDocument, ISerializable
{

    ...

    protected ResourceXmlDocument(SerializationInfo info, StreamingContext context)
    {
        if (info == null) throw new System.ArgumentNullException("info");
        Load(info.GetString("content"));
    }


    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null) throw new System.ArgumentNullException("info");
        info.AddValue("content", this.OuterXml);
    }

Yossi Dahan比较了这些方法(映射、分配和使用未记录的API)

API方法使用Microsoft.BizTalk.Component.Interop.DocumentSpec-引用,但正如Yossi提到的,它比maps或XmlDocument.LoadXml慢得多

请注意以下用法:

  • 程序集是TestSchema,版本=1.0.0.0,区域性=中性,publicKeyToken=XXXXXXXXXXXXXX”
  • schemaName是TestSchema.MyTestSchema[+myRootNode1]
  • 注意是版本相关的-如果程序集版本更改,则创建将失败,除非还更新版本字符串
  • 以这种方式创建的新消息不一定对XSD有效。e、 g.DateTimes和Int将只是空元素,即使它们是nillable(这不会在XML中设置nillable=true)

转换需要源消息,而我没有。这不需要外部库吗?如果是这样,如何在项目之间保持xsd模式的同步?你有一些教程可以让我学习吗?如果你不想使用外部程序集,你可以在与业务流程相同的程序集中创建静态辅助对象。我想问一下如何创建,但后来我复制/粘贴了一个cs文件到。。。它看起来很好。这也会在其他方面对我有所帮助,所以我现在将对其进行升级。事实上,不高兴,该类在bt项目中,它并不抱怨它,但在赋值形状中我看不到类型。你确定该类与你的编排类型在同一命名空间中吗?@nonnb总是很乐意提供帮助。在我们的环境中,这是一个非常健壮的解决方案。我会尝试一下,但我刚刚发现了一些东西。当我显示所有文件时,我发现一个.cs文件不是项目的一部分。该文件包含所有架构元素的可序列化类(由Microsoft.BizTalk.schema.Compiler自动生成,3.0.1.0)。但是,如果我包含该文件,它仍然无法在分配形状中看到它。@mmix您需要声明这种类型的变量(业务流程视图)才能在分配形状中使用它。不,声明变量无效,原因与Hugh的建议无效相同。看来您的解决方案是唯一合理的,它是Biztalk的一个非常奇怪的限制,imho。他们是否真的如此脱离现实,以至于他们认为没有人愿意从头开始创造信息?无论如何,为了保持一致性,我会尝试你的建议,如果它有效,我会接受你的答案。@mmix好的,基本上每个构造消息形状都会从头开始创建一条消息-在你的例子中,棘手的部分是填充值(而不是映射或复制源消息)。如果你提升每个字段(只有当它们是非重复节点时才有效),你可以简单地赋值。Yossi会说话,但不会走路,我猜他认为我们都处于这个级别。也许有一天,但不是今天,因为他没有做任何样品,我真的不知道如何使用他的建议。至于第二个,我不想使用未记录的功能(多年后,它们总是会导致讨厌的电话)
[Serializable]
public class ResourceXmlDocument : XmlDocument, ISerializable
{

    ...

    protected ResourceXmlDocument(SerializationInfo info, StreamingContext context)
    {
        if (info == null) throw new System.ArgumentNullException("info");
        Load(info.GetString("content"));
    }


    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null) throw new System.ArgumentNullException("info");
        info.AddValue("content", this.OuterXml);
    }