以下のコード内の混合要素のコンテンツを取得する最適な方法は何ですかbody
? 要素には XHTML またはテキストのいずれかが含まれている可能性がありますが、そのコンテンツを文字列形式で取得したいだけです。 type には、まさに私が求めているプロパティがXmlElement
あります。InnerXml
書かれたコードほとんど望みどおりの動作をしますが、周囲の<body>
...</body>
要素が含まれており、これは望ましくありません。
XDocument doc = XDocument.Load(new StreamReader(s));
var templates = from t in doc.Descendants("template")
where t.Attribute("name").Value == templateName
select new
{
Subject = t.Element("subject").Value,
Body = t.Element("body").ToString()
};
ベストアンサー1
これらの提案されたソリューションのどれが最も優れているかを確認したかったので、比較テストをいくつか実行しました。興味深いことに、LINQメソッドと従来のメソッドも比較しました。システム.Xmlグレッグが提案した方法。バリエーションは面白く、予想外だった。最も遅い方法は最速より3倍以上遅い。
結果は最速から最遅の順に並べられています:
- CreateReader - インスタンスハンター (0.113 秒)
- 昔ながらの System.Xml - Greg Hurlman (0.134 秒)
- 文字列連結による集計 - Mike Powell (0.324 秒)
- StringBuilder - Vin (0.333 秒)
- 配列の String.Join - Terry (0.360 秒)
- 配列上の String.Concat - Marcin Kosieradzki (0.364)
方法
私は 20 個の同一ノード (「ヒント」と呼ばれる) を持つ単一の XML ドキュメントを使用しました。
<hint>
<strong>Thinking of using a fake address?</strong>
<br />
Please don't. If we can't verify your address we might just
have to reject your application.
</hint>
上記の秒数で示されている数字は、20ノードの「内部XML」を1000回連続で抽出し、5回の実行の平均を取った結果です。XMLをロードして解析するのにかかった時間は含まれていませんXmlDocument
(システム.Xmlメソッド) またはXDocument
(その他すべて)。
私が使用した LINQ アルゴリズムは次のとおりです。(C# - すべてXElement
「親」を受け取り、内部の XML 文字列を返します)
リーダーを作成:
var reader = parent.CreateReader();
reader.MoveToContent();
return reader.ReadInnerXml();
文字列連結による集計:
return parent.Nodes().Aggregate("", (b, node) => b += node.ToString());
文字列ビルダー:
StringBuilder sb = new StringBuilder();
foreach(var node in parent.Nodes()) {
sb.Append(node.ToString());
}
return sb.ToString();
配列のString.Join:
return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());
配列上の String.Concat:
return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());
ここでは、ノード上で .InnerXml を呼び出すだけなので、「単純な古い System.Xml」アルゴリズムは示していません。
結論
パフォーマンスが重要な場合(例えば、大量のXMLを頻繁に解析する場合)、CreateReader
毎回ダニエルの方法を使ういくつかのクエリを実行するだけの場合は、Mike のより簡潔な Aggregate メソッドを使用することをお勧めします。
多数のノード (おそらく 100 個) を持つ大きな要素で XML を使用している場合、StringBuilder
Aggregate メソッドよりも を使用する利点がわかるでしょうが、 よりも優れているとはCreateReader
思えません。大きなリストを大きな配列に変換するというペナルティがあるため (ここでは小さなリストでも明らかです)、これらの状況ではJoin
およびConcat
メソッドの方が効率的であることはないと思います。