65.9K
CodeProject 正在变化。 阅读更多。
Home

在 BizTalk 2004/2006 中利用 XLINQ 概念 +

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.83/5 (3投票s)

2006 年 7 月 29 日

CPOL

2分钟阅读

viewsIcon

34547

downloadIcon

182

编写简短的代码来解决您复杂的难题。

引言

在本文中,我提出了在 BizTalk 2004/2006 和未来版本中利用 XLINQ 概念的想法。 XLINQ 是 LINQ 的一部分,是对 C# 语言的增强。 请注意,在撰写本文时,LINQ 增强功能处于 CTP 阶段,因此我们不能将其视为概念验证。

什么是 XLINQ?

LINQ(语言集成查询)是一组 .NET Framework 语言扩展的代码名称。 这是一种通过构建像 SQL 这样的表达式来访问数据的巧妙方法。 DLINQ 是一组组件,可帮助在 SQL 和 LINQ 之间转换数据。

XLINQ 是一种简单轻量级的 XML API,旨在从内存和性能的角度简化 XML 的使用。

场景

在 2003 年,我使用 BizTalk 2004 将 Siebel CME 与我们客户端网络中的其他应用程序集成。 Siebel 公开 UAN(通用应用程序网络)层,用于与外部应用程序共享通用模式。 Siebel CME UAN 2.0 包提供了 12 个业务流程与其他系统集成,其中之一是 ProcessBilling 流程,用于更新订单,其中包含有关每个单独订购的行项目的信息。 源消息如下所示

<Orders>
    <LineItem Code="101"> 
        <User ID="UI023">
            <Product> <OpCode>ADD</OpCode>    
            <Name>Product A</Name>     <Qty> 1</Qty> </Product>   
        </User>
        <User ID="UI023">
            <Product> <OpCode>UPDATE</OpCode>   
            <Name>Product B</Name> </Product>
        </User>
        <User ID="UI024">
            <Product> <OpCode>ADD</OpCode>
            <Name>Product D</Name>  </Product>   
        </User>
        <User ID="UI024">
            <Product> <OpCode>UPDATE</OpCode>   
            <Name>Product E</Name>   </Product>
        </User>
    </LineItem >
    <LineItem Code="102"> 
        <User ID="UI023">
            <Product> <OpCode>DELETE</OpCode>    
            <Name>Product C</Name>   </Product>   
        </User>
        <User ID="UI024">
            <Product> <OpCode>UPDATE</OpCode>    
            <Name>Product D</Name>    </Product>   
        </User>
        <User ID="UI024">
            <Product> <OpCode>ADD</OpCode>   
            <Name>Product F</Name>        </Product>
        </User>
    </LineItem >
</Orders>

目标系统 Portal net 公开了每个用户的三个 Web 服务方法,例如“Add”、“Modify”和“cancel”。 我们必须根据订单 ID、用户 ID 和 OpCode 对大型 XML 进行排序和分组,并调用 Infranet 来处理具有排序结果的订单。 我们尝试编写自定义 XSLT,但在聚合数据时遇到困难,这存在很大的性能问题。 然后我们选择了 .NET C# 帮助类,并编写了如下代码

private static XmlDocument GetListSortedByUser(XmlDocument document, 
    out int RecCount)
{
            //Main arraylist to store the ordelines as it is from source
            ArrayList arrOrderLineItemsList = new ArrayList();
            // Get the order lines node list
            XmlNodeList xmlunl =  document.SelectNodes(xpathOrderLines,nsmgr);
            
            ArrayList objUserOperationCodeList = new ArrayList();
            
            // iterate for each order line and navigate through each order
            // line and add the operation code, orderid, and user id to the 
            // arraylist Towards the end of this for each loop add it to  
            // the main array
            foreach(XmlNode xmlNodeRdr in xmlunl)
            { ……………………………..
                if (xmlNodeRdr.SelectSingleNode(xpathOrderId,nsmgr) != null)
                { ………………..
                }

                // Add Operation Code to the array arrUserOperationCodeList 
                if (xmlNodeRdr.SelectSingleNode(xpathOperationCode,
                    nsmgr) != null)
                {
                    ….
                }
                // Get the party node list
                XmlNodeList xmlparty =  xmlNodeRdr.SelectNodes(xpathParty,
                    nsmgr);
                foreach(XmlNode xmlNodeParty in xmlparty)
                {
                if (xmlNodeParty.SelectSingleNode(xpathPartyRole,
                    nsmgr) != null)
                    {
                    ……………….    
                    }
                }
            // Separate Arraylist to hold the orderline values stored above based on the 
            // operation code
            // Delete operation code arraylist
            ArrayList arrDeleteList = new ArrayList();
            // Add operation code arraylist
            ArrayList arrAddList = new ArrayList();
            // Update operation code arraylist
            ArrayList arrUpdateList = new ArrayList();

            // For loop to add each order line to its arraylist based on its 
            // operation code value
            for(int i = 0; i lessthan objUserOperationCodeList.Count; i++)
            {
                object eachLineDetails;
                eachLineDetails = objUserOperationCodeList[i];
                ArrayList tempArrayList = new ArrayList();
                tempArrayList = (ArrayList)eachLineDetails;

                if(tempArrayList[1].ToString().Trim() == "Delete")
                    arrDeleteList.Add(objUserOperationCodeList[i]);
                if(tempArrayList[1].ToString().Trim() == "Add")
                    arrAddList.Add(objUserOperationCodeList[i]);
                if(tempArrayList[1].ToString().Trim() == "Update")
                    arrUpdateList.Add(objUserOperationCodeList[i]);
            }
            arrDeleteList = PerformSort(arrDeleteList);
            // Call the method to perform sort on add arraylist
            arrAddList = PerformSort(arrAddList);
            // Call the method to perform sort on update arraylist
            arrUpdateList = PerformSort(arrUpdateList);

            objUserOperationCodeList.Clear();

            // Add the sorted Delete arrayList to this new arraylist
            for (int i=0; i lessthan arrDeleteList.Count;i++)
            {
                objUserOperationCodeList.Add(arrDeleteList[i]);
            }
            // Add the sorted Add arrayList to this new arraylist
            for (int i=0; i lessthan arrAddList.Count;i++)
            {
                objUserOperationCodeList.Add(arrAddList[i]);
            }
            // Add the sorted Update arrayList to this new arraylist
            for (int i=0; i lessthan arrUpdateList.Count;i++)
            {
                objUserOperationCodeList.Add(arrUpdateList[i]);
            }
                    
            // the for loop to iterate through each order line and 
            // construct the xml back
            // from the grouped and sorted values in arraylist
            int iter=0;
            // iterate through each order line node
            foreach(XmlNode xmlNodeRdr in xmlunl)
            {
                document = new XmlDocument();
            }
return document;
}

编写了将近 300 行 C# 帮助代码,仅用于排序和分组。

我们如何在 XLINQ 中实现相同的功能?

XElement OrdersGrp = 
    new XElement("Orders",
    from user in orders.Descendants("User")
    from userid in user.Attributes("ID")
    group user by (string)userid into userGroup
    let userid = userGroup.Key
    select 
        new XElement("User",
        new XAttribute("ID",
        userid), 
        from user in userGroup 
        from opCode in user.Descendants("OpCode")
        group user by (string)opCode into opCodeGroup
        let opCode = opCodeGroup.Key
        select 
            new XElement("Product", 
            new XElement("OpCode",
            opCode), 
            opCodeGroup.Descendants("Name")
         )));

只有一行? ??? (好吧,我用 ; 分号来计算行数)这是您期望的输出

<Orders>
  <User ID="UI023">
    <Product>
      <OpCode>ADD</OpCode>
      <Name>Product A</Name>
     </Product>
    <Product>
      <OpCode>UPDATE</OpCode>
      <Name>Product B</Name>
      </Product>
    <Product>
      <OpCode>DELETE</OpCode>
      <Name>Product C</Name>
      </Product>
  </User>
  <User ID="UI024">
    <Product>
      <OpCode>ADD</OpCode>
      <Name>Product D</Name>
      <Name>Product F</Name>
      </Product>
    <Product>
      <OpCode>UPDATE</OpCode>
      <Name>Product E</Name>
      <Name>Product D</Name>
     </Product>
  </User>
</Orders>

结论

XLINQ 开辟了一种新方法来简化您对 XML 的数据访问,从而使您能够开发非常高效的 Biztalk 接口。

可以对 Biztalk 消息进行排序和分组。 如果有人有兴趣,他们可以编写一个通用 functoid 用于在映射中对消息进行排序。

在此处获取您的源代码。

开始梦想您在 XLINQ 中的下一步,并告诉我您的更新... 干杯。

本文中的所有代码均已使用 Microsoft LINQ 项目 2006 年 5 月 CTP 编译。

历史

  • 2006 年 7 月 29 日:首次发布
© . All rights reserved.