1

私の目標

Placement_ID と Fill_ID の組み合わせに基づいて、ドキュメントに動的に表示される XElement を作成する必要があります。オブジェクト リスト内のレコードが別のレコードと同じ Placement_ID を持っている場合、別の Fill XElement を前のものの下に別の Fll_ID で追加したいと考えています。以下の例:

<envelope ack="entity" transaction="multi">
  <auth>
        <user>TM_DEV</user>
        <session>session1</session>
  </auth>
  <Trading op="createOrder, pretradeCpl, sendToTrading,createPlacement, createFill" id="os1">
        <order op="create" id="test1234">
              <scenario id="sample" />
              <execBroker>BEAR</execBroker>
              <ticker>MSFT</ticker>
              <trader>TM_DEV</trader>
              <instruction>LIM</instruction>
              <limitPrice>85</limitPrice>
              <transType>BUYL</transType>
              <orderDuration>GTC</orderDuration>
              <tradeDate>
              </tradeDate>
              <settleDate>
              </settleDate>
              <allocation id="" op="create">
                    <acctCd>tstacc00006</acctCd>
                    <targetQty>300</targetQty>
                    <specialInst />
              </allocation>
              <placement id="Place1" op="create">
                    <execBroker>BEAR</execBroker>
                    <placeQty>300</placeQty>
                    <fill id="fill1" op="create">
                          <fillQty>150</fillQty>
                          <fillPrice>43</fillPrice>
                    </fill>
                    <fill id="fill2" op="create">
                          <fillQty>150</fillQty>
                          <fillPrice>44</fillPrice>
                    </fill>
              </placement>
        </order>
  </Trading>

私の進歩

これまでに書いた以下のコードは、リスト オブジェクトを照会し、各行の新しい順序を生成します。リストを Placement_ID でグループ化できるようにする必要があり、それらが同じ Placement_ID を持つ 2 つの行である場合は、複数の Fill 要素を書き込む必要があります。それ以外の場合、Placement_ID が重複していなければ、リスト内のデータ行ごとに 1 つの注文、1 つのプレースメント、および 1 つの約定があります。

XDocument doc = new XDocument(
           new XDeclaration("1.0", "UTF-8", "yes"),
          new XElement("envelope",
          new XAttribute("ack", "entity"),
          new XAttribute("transaction", "multi"),
           new XElement("auth",
           new XElement("user", "TM_DEV"),
           new XElement("session", "session1")),
           new XElement("trading",
               new XAttribute("op", "createOrder, pretradeCpl, sendToTrading, createPlacement, createFill"),
               new XAttribute("id", "os1"),
           from t in trades.ToList()
           select new XElement("order",
                   new XAttribute("op", "create"),
                   new XAttribute("id", DateTime.Now.ToString("yyMMddHHmmssfff") + t.OrderId),
                   new XElement("Scenario",
                       new XAttribute("id", "sample")),
                   new XElement("execBroker", t.ExecBrkID),
                   new XElement("ticker", t.Ticker),
                   new XElement("sedol", t.Sedol),
                   new XElement("Trader", "TM_DEV"),
                   new XElement("transType", t.TransType),
                   new XElement("orderDuration", "GTC"),
                   new XElement("tradeDate", ""),
                   new XElement("settleDate", ""),
                   new XElement("allocation",
                       new XAttribute("id", ""),
                       new XAttribute("op", "create"),
                       new XElement("acctCd", t.Account),
                       new XElement("targetQty", t.TargetQty),
                       new XElement("specialInst", "who to settle with")),
                   new XElement("placement",
                       new XAttribute("op", "create"),
                       new XAttribute("id", t.PlacementId),
                       new XElement("execBroker", t.ExecBrkID),
                       new XElement("placeQty", t.ExecQty),
                       new XElement("fill",
                           new XAttribute("id", t.FillId),
                           new XAttribute("op", "create"),
                       new XElement("fillQty", t.ExecQty),
                       new XElement("fillPrice", t.ExecPrice)))))));

アップデート

あなたの提案を使用して、更新の例を分解しました。「ドキュメントの形式が正しくありません」というエラーが表示されるようになりました。

using (XmlWriter xw = XmlWriter.Create(s, xws)){


XElement order = new XElement("order");
var groupedOrders = trades.GroupBy(o => o.OrderId);

foreach (var groupie in groupedOrders)
{
    int n = 1;
    XElement root = new XElement("placement",
                    from g in groupie
                       select new XElement("t",
                                new XAttribute("op", "create"),
                              new XAttribute("id", g.Ticker)));                    
    foreach (var fill in groupie)
    {
        XElement newFillElement = new XElement("fill" + n,
                                    new XAttribute("id", fill.PlacementId),
                                   new XAttribute("op", "create"),
                                    new XElement("fillQty", fill.ExecQty),
                                    new XElement("fillPrice", fill.ExecPrice));
        root.Add(newFillElement);
        n++;   
    }

    order.Add(root);
}

XDocument doc = new XDocument(
                    new XDeclaration("1.0", "UTF-8", "yes"), order);
doc.Save(xw);

}

4

2 に答える 2

1

一見すると、1 回のパスでやりすぎているように見えます。ベース ドキュメントを作成することは良いことだと思いますが、条件付きで塗りつぶしを追加する必要がある場合は、別の戦略が必要です。

注文をループする前に、LINQ を使用して Placement_ID で注文をグループ化することをお勧めします。これにより、グループ要素が同じ Placement_ID であることが保証され、適切な数のfills.

擬似コード:

var groupedOrders = listOfOrders.GroupBy(o => o.Placement_ID);
foreach (var group in groupedOrders)
{
    //Create document, but don't add any fills
    XDocument doc = new XDocument(...)

    int n = 1;
    foreach (var fill in group)
    {
        //Same structure as before, just a separate element
        XElement newFillElement = new XElement("fill" + n, ...);

        //Add as last element to existing doc
        doc.Add(newFillElement);

        n++
    }
}

参照:
101 LINQ の例、LINQ -
XML でデータを追加、更新、および削除するグループ化演算子

于 2012-12-27T21:02:27.763 に答える
0

xml 構築の外部で関係を作成し、そこから xml を再構築できますか? それはあなたが言っているように思えます。要素と属性のxmlに必要なすべてのデータである一般的なリストを作成できる可能性があります。その中にxmlをダンプしてから、それをエクスポートします。一連のルールとなる動的エキスパンドを追加します。Linq to XML を使用して、xml を汎用リストに照会します。

概念を理解する必要があるだけなので、あなたの例ほど激しいことをするつもりはありません。「子孫」メソッドでカウントやその他の操作を直接実行できる場合がありますが、私は通常、最初にリストの内容を確認してから、自分が何を持っているかを確認することを好みます

XML の例:

<Orders>
  <Person Name="Brett">
    <Order Name="thing"/>
  </Person>
  <Person Name="Joe">
   <Order Name="thing"/>
   <Order Name="thing2" />
  </Person>
</Orders>

C# の例:

using System;
using System.Linq;
using System.Xml.Linq;

namespace TestLinqXml
{
    public class Program
    {
        private static void Main(string[] args)
        {
            // load original doc
            var doc = XDocument.Load(@"C:\TestCode\TestLinqXml\TestLinqXml\XML\Orders.xml");

            // query it with Linq using lambda patterns.
            var list = doc.Descendants("Person")
                          .Select(x => new 
                                  // expand descendents out into a class I make up below by declarining new and defining object
                                  {
                                      Name = x.Attribute("Name").Value,
                                      OrderCount = x.Descendants("Order").Count()
                                  }
                );

            // recreate the new doc
            XDocument newdoc = new XDocument(
                new XDeclaration("1.0", "UTF-8", "yes"),
                new XElement("person",
                             list.Select(n =>
                                         new XElement(n.Name,
                                                      new XAttribute("OrderCount", n.OrderCount)
                                             ))
                    )
                );

            // save it
            newdoc.Save(@"C:\TestCode\TestLinqXml\TestLinqXml\XML\output.xml");
        }
    }
}
于 2012-12-27T22:02:01.463 に答える