再帰クエリで根付き木
再帰クエリで根付き木を解くコード。
using System.Collections.Generic; using System.Linq; namespace RootedTree { class Program { static void Main(string[] args) { // NodeId,ParentNodeId string[,] src = new string[9,2]{ {"A101", ""}, {"A201", "A101"}, {"A202", "A101"}, {"A301", "A201"}, {"A302", "A201"}, {"A303", "A201"}, {"A304", "A201"}, {"A401", "A302"}, {"A402", "A304"}, }; // Setに全てのNode情報を格納 HashSet<Node> nodeSet = new HashSet<Node>(); for (int i = 0; i < src.GetLength(0) ;i++) { Node node = new Node(); node.NodeId = src[i, 0]; node.ParentNodeId = src[i, 1]; nodeSet.Add(node); } // 最上位のノードを探す var startNode = nodeSet .Where(e => "".Equals(e.ParentNodeId)) .Select(e => e) .First(); // 最上位から探索開始 search(nodeSet, startNode, 0); System.Console.WriteLine(); } /// <summary> /// 子のノードを探す /// </summary> /// <param name="nodeSet">全てのノードのSet</param> /// <param name="startNode">始点ノード</param> /// <param name="depth">階層の深さ</param> private static void search(HashSet<Node> nodeSet, Node startNode, int depth) { System.Console.WriteLine(new string(' ', depth) + startNode.NodeId); // 始点ノードの子ノードを取得する var childNodes = nodeSet .Where(e => startNode.NodeId.Equals(e.ParentNodeId)) .Select(e => e); if (childNodes.Count() > 0) { // 子ノードがある場合 foreach (Node child in childNodes) { // 子ノードの更に下を探索 search(nodeSet, child, depth + 1); } } System.Console.WriteLine(new string('-', depth) + startNode.NodeId); } } /// <summary> /// ノードを表すクラス /// </summary> class Node { public string NodeId; public string ParentNodeId; } }
結果
A101
-A201
--A301
==A301
--A302
---A401
===A401
==A302
--A303
==A303
--A304
---A402
===A402
==A304
=A201
-A202
=A202
A101
【メモ】XPathについて
XSLTとは
・XMLそのもほなデータの論理的な構造を示すもの。どんな体裁でWebブラウザや紙などに表示されるべきかを指示するレイアウト情報は含まれていない。
・XMLデータの構造変換を指定する部分を、独立した規格として取り出したのがXSLT。
XPathとは
・XSLTによるXML→別の文書への変換に際し、元のXML文書の「どの要素からデータを取り出すか」を指定する必要がある。
・指定方法の規則がXPath。
・XML文書をツリー構造としてみたときに、ルートノードを起点に各ノードへの位置を指定できるようにする。
XPathの記法
とくにこちらを見ると、かなり柔軟な指定方法ができることがわかる。
【メモ】ネットワーク上にSVNサーバをたてる
複数名で開発を進めるような場合、ネットワーク上の端末などにSVNリポジトリを構築することが多いと思う。 (backlogとかGitHubとかのクラウドサービスはまた少し話が違うが)
そのとき、ソースをチェックアウトする側のクライアントとは違い、リポジトリはあくまで「サーバ」としての構築が必要となる。
どういうことか。TortoiseSVNの下記のドキュメント参照してみる。
ネットワークフォルダー上のリポジトリへのアクセス
原理上、FSFSリポジトリはネットワークフォルダー上に配置でき、file://プロトコルを用いて複数のユーザーからアクセスできますが、これは絶対にお勧め しません 。
(略)
file:// アクセスは、ローカルでの1ユーザーのみのアクセスを想定しており、そのようにテストとデバッグを行っています。リポジトリを共有したい場合は、 まさに 適切なサーバーをセットアップする必要がある場面であり、それは見かけほど難しくはありません。
TortoiseSVNは、理論上、リポジトリもクライアントもTortoiseSVNのみで完結できる。そしてこの時は「file://プロトコル」を用いる。
しかし、「複数名によるリソースへのアクセス」という観点からいうと、
誰からも直接アクセスできてしまうことで、リポジトリを壊してしまうことがある。
ファイルのロックやアクセス権の管理がうまくできないことがある。 などの問題が生じる。
そこで、サーバーをセットアップし、「svn://プロトコル」「http://プロトコル」でアクセスさせるのが望ましい。
SVNサーバの構築には、たとえば下記が使える。
自分のローカル端末で開発をして、TortoiseSVNでソースのバージョン管理をしていたときは、リポジトリ側(サーバ)もチェックアウト側(クライアント)もローカルなので意識していなかったのだが、ようやく学習した。