UniProtKB の XML を LINQ で処理


世界には沢山の優れた遺伝情報のデータベースが存在します。 UniProtKB はその 1 つで,タンパク質のデータベースです (knowledge base)。 UniProt を私が好む理由としてはクエリでレビューされているタンパク質のみを簡単にピックアップできることが第一ですが, GET メソッドで簡単にスキーマ付きの XML の結果が取得できることもあります。実際のところ欲しいのは配列なので FASTA 形式で取得しても良いのですが,どの染色体上の遺伝子だとか,遺伝子の機能をローカルに保存しておくと便利です。

LINQ to XML は必要な情報を XML にマッピングするのに非常に便利です。しかし,データベースのような,巨大なデータを扱うには少し工夫が必要です。

例えばアミノ酸配列情報だけを取得したい場合は以下のようになります。

const string UniProtXmlNamepace = "http://uniprot.org/uniprot";

[STAThread]
static void Main()
{
	XNamespace xmlns = UniProtXmlNamepace;
	var entries = from entry from GetEntries("test.xml")  // 適当なファイルを落としてテスト。
		select new XElement("entry",
			entry.Element(xmlns + "sequence")
		);
	XStreamingElement root = new XStreamingElement("entries", entries);

	using (XmlWriter writer = XmlWriter.Create(Console.Out))
	{
		root.WriteTo(writer);
	}
}

private static IEnumerable GetEntries(string uri)
{
	using (XmlReader reader = XmlReader.Create(uri))
	{
		reader.MoveToContent();
		while (reader.Read())
		{
			if (reader.NodeType == XmlNodeType.Element && reader.LocalName == "entry")
			{
				yield return (XElement)XElement.ReadFrom(reader);
			}
		}
	}
}

ポイントは XStreamingElement で遅延処理を行うことです。

まあ LINQ を用いなくても XmlReader でそのまま処理を進めて言っても良いのですが, LINQ を使うと処理の流れを追う必要がなくなるので見やすくなって良いと思います。