-1

複数の Invoice 要素を含む XML 入力があります。これらの要素から送り状オブジェクトを作成します。請求要素の位置に基づいて、シーケンス番号を割り当て、別の要素 (StatusMsg) から対応するメッセージを見つける必要があります。

.Net 4.0 に次の C# コードがあります。それはうまく機能し、適度に読みやすいです。performance犠牲にすることなく、より良いコードはありますreadabilityか?

コード

// Create a collection of invoice elements
var invoiceEntities = xDoc.Descendants("Invoice")
              .Select(x => new Invoice
               {
                  Vendor = x.Element("Vendor") == null ? String.Empty : x.Element("Vendor").Value.Trim(),
                  Amount = x.Element("Amount") == null ? String.Empty : x.Element("Amount").Value.Trim()
               });

List<Invoice> invoices = invoiceEntities.ToList();

//Iterate all entities for finding corresponding message element and update the entity's Message

int count = 0;
foreach (Invoice entity in invoices)
{
           count++;

           //Dynamic XPath statement
           string messagePath = @"Status/StatusMsg/StatusDetail/Sequence[text()=" + count.ToString() + "]/../Message";
           var statusDetails = xDoc.XPathSelectElements(messagePath).FirstOrDefault();
           if (statusDetails != null)
           {
               entity.Message = statusDetails.Value;
               entity.Sequence = count;
           }

  }

実在物

public class Invoice
{
    public string Vendor { get; set; }
    public string Amount { get; set; }
    public string Message { get; set; }
    public int Sequence { get; set; }
}

XML

  XDocument xDoc = XDocument.Parse(@"  
          <Status>
                <StatusMsg>
                    <StatusType>INVOICE</StatusType>
                    <StatusCode>READYPAY</StatusCode>
                    <StatusTimestamp>2013-03-19T21:20:54Z</StatusTimestamp>

                    <StatusDetail>
                        <Sequence test=""K"">  2  </Sequence>
                        <Message>STL MESSAGE </Message>
                    </StatusDetail>

                    <StatusDetail>
                        <Sequence test=""1"">  1  </Sequence>
                        <Message>AKP MESSAGE</Message>
                    </StatusDetail>

                    <StatusDetail>
                        <Sequence> 1 </Sequence>
                        <Message>CC</Message>
                    </StatusDetail>

                </StatusMsg>
                <Invoices> 

                    <Invoice>
                        <Vendor>
                         AKP LLC
                        </Vendor>
                        <Amount>
                         100
                        </Amount>
                    </Invoice>

                    <Invoice>
                        <Vendor>
                         STL Inc
                        </Vendor>
                        <Amount>
                         20950
                        </Amount>
                    </Invoice>

                </Invoices>
            </Status>
           ");

参考文献

  1. C# オブジェクト コードを生成し、xml ドキュメントからそのプロパティに値を割り当てる
  2. 注釈を使用して LINQ to XML ツリーを XSLT スタイルに変換する - Eric White
  3. XSLT または Linq to XML の利点
4

1 に答える 1

1

私が本当にお勧めできる唯一のことは、StatusDetailノードもリストに保存することです。ノード全体を一度取得するだけで、2番目のlinqステートメントを介してリストを参照して、シーケンスをフィルタリングできます。ただし、単純に XPath 文字列を作成して再利用するよりも、最終的には遅くなる可能性があります。

var Details = xDoc.Descendants("StatusDetail").ToList();

...

var statusDetail = Details.Where(a => a.Sequence == count).FirstOrDefault();

うるさい開発ポイントとして、通常、そのString.Formatような奇妙に連結された文字列を行うときに使用することをお勧めします...バックコードがより効率的であることについての何か...

string messagePath = String.Format("Status/StatusMsg/StatusDetail/Sequence[text()={0}]/../Message", count);

もう 1 つのオプションとして、既に匿名型を作成しています。Invoice オプションにカウントを組み込むことができない本当の理由はありません。これにより、少なくともループ内でカウントを個別に宣言して維持する必要がなくなります。

int count = 1;

var invoiceEntities = xDoc.Descendants("Invoice")
          .Select(x => new Invoice
           {
              Vendor = x.Element("Vendor") == null ? String.Empty : x.Element("Vendor").Value.Trim(),
              Amount = x.Element("Vendor") == null ? String.Empty : x.Element("Amount").Value.Trim(),
              Index = count++
           });//yes that works, I tested it because even I wasn't sure, but Index is correct and different for each element
于 2013-03-20T13:13:10.693 に答える