PowershellのXPathNavigatorでXMLパース2018/04/30PowerShell仕事でやったことのメモ。XMLファイルで記述された文書をPowerhsellでパースし、必要な情報を取り出す方法です。Languageの略。html同様マークアップ言語ですが、htmlとは違い属性を自由に定義できるため、アプリケーションのコンフィグファイル等によく利用されています。Tomcatの設定なんかもXML形式。ファイルの先頭にはXML宣言を書きます。この文書はXMLですよという宣言。standalone="yes">1versionというのはXMLのバージョン。現在は1.0以外ありません。encodingはその名の通り文字のエンコーディング形式。standaloneというのはこの文書がスタンドアロン文書かどうか。XMLは外部の文書を読み込むこともできるそうです。こんな行があったとします。Hat">CentOS</Linux>1Linuxの位置にあるものは「要素」。Linux要素の開始タグと終了タグで囲まれたCentOSが「コンテンツ」。distributorの位置にあるものはLinux要素が持つ「属性」。こんな感じで、XMLは「要素」が「コンテンツ」を持ち、要素の付加的な情報を「属性」で記述していく文章です。マークアップ言語なので、要素は子要素を持つことができます。htmlでよく見るやつですね。distributor="Microsoft">Windows10</Windows></OS>1234一つの要素は属性を複数持つこともできます。属性の順番は意味をなしません。desktopmanager="GNOME">CentOS</Linux>1コンテンツを含まない要素もあります。その場合、htmlと同様にスラッシュを開始タグの末尾につけることで、終了タグを省略できます。省略した書き方を「空要素タグ」と呼んだりします。PowershellとXML仕事でXMLから情報を取り出さなあかんくなったので、やっぱどんな環境でも使えるツールが一番いいんだろうなぁと思ってPowerhsellとXMLについて調べました。PowershellにはクラスとしてXML型が存在します。こんな文書をtest.xmlとして作成します。distributor="Microsoft">Windows10</Windows></OS>12345そしてこのファイルの中身をGet-Contentで取得し、変数に代入します。その際、データ型としてXMLと指定します。.\test.xml)1こうすることで、要素をドット区切りで取得できるようになります。オブジェクトのプロパティを取得していくイメージですね。CentOS1234567891011属性は、XMLの要素(XmlElement)クラスのGetAttributeメソッドを利用します。Hat12属性の単純なgetとsetは可能なのですが、検索だとか件数カウントだとかが微妙に使いづらい。ある属性を持つ要素だけを絞り込んでそのコンテンツを取得する、なんてことはちょっとしたロジックを書いてやらなきゃいけない。foreach文回して全部書き出してそこから選択する、とかね。そこで登場するのがPowershellのXPathNavigatorオブジェクト。PowershellとXPathNavigatorXMLクラスの持つCreateNavigator()メソッドを利用すると、XMLオブジェクトをXPathNavigatorオブジェクトに変換することができます。${MYXML}.CreateNavigator()12これ何かというと、XPathExpressionクラスが提供するXPath式という表記方法と併用することで、XML文書をパス区切りのディレクトリのような木構造として扱えるオブジェクトです。基本的な使い方は、XPathNavigatorクラスの持つSelect()メソッドにてXPath式を記述し、XML文書を検索していきます。見れば大体書いてあります。例1.OS要素の子要素のうち、distributorがMicrosoftの全要素を出力するこんな感じ。Windows1012345678910111213141516171819202122232425262728オブジェクトなのでいろんな情報がひっついてきます。コンテンツだけでよければ、Select()した結果の.Valueプロパティを取得すればOK。例2.desktopmanager属性がGNOMEである要素のdistributor属性を出力するこんな感じ。2つ目のスラッシュ区切りの部分は、全て(*)の要素から角括弧でくくった部分で属性条件を指定して要素集合(属性、コンテンツを含む)を絞りこむという意味。その絞り込んだ結果のdistributor属性を表示しています。何かっつうとNmapの-oXオプションが吐くXMLファイルから各スキャン(UDP、Connect、サービススキャン、etc)にかかった時間を出力するスクリプト。GitHub始めました。https://github.com/uda-cha/CalcTimeNmapXMLおわり。