2012-03-16 12 views
0

共有フォルダにログファイルがあります。 (最初はルート要素のみを持ちます)。xmlファイルにログデータを追加する方法は?

ログデータをXMLに追加する必要があるため、ユーザーがpowershellスクリプトを実行するたびに、最初のユーザー(デビッド)は、スクリプトを実行すると

<VM> 
    <VMName>Fresh_R2VM</VMName> 
    <AccessedBy>David</AccessedBy> 
    <AccessedDate>Today's date</AccessedDate> 
    <AccessedTime>current Time</AccessedTime> 
</VM> 

私のXMLログファイルには、この

<VirtualMachines version="1.0"> 

</virtualMachines> 

のように最初になり、私のログファイルは次のようにする必要があります。

<VirtualMachines version="1.0"> 
<VM> 
    <VMName>Fresh_R2VM</VMName> 
    <AccessedBy>David</AccessedBy> 
    <AccessedDate>Today's date</AccessedDate> 
    <AccessedTime>current Time</AccessedTime> 
</VM> 
</virtualMachines> 

davidが2回実行される場合は、もう1つのエントリを追加する必要があります。

<VirtualMachines version="1.0"> 
    <VM> 
     <VMName>Fresh_R2VM</VMName> 
     <AccessedBy>David</AccessedBy> 
     <AccessedDate>Today's date</AccessedDate> 
     <AccessedTime>current Time</AccessedTime> 
    </VM> 

    <VM> 
     <VMName>Fresh_R2VM</VMName> 
     <AccessedBy>David</AccessedBy> 
     <AccessedDate>Today's date</AccessedDate> 
     <AccessedTime>current Time</AccessedTime> 
    </VM> 
    </virtualMachines> 

私は、ファイルを記録し、内容を更新するために、テンプレートのクローンを作成し、この使用したテンプレートXMLファイルを達成しようとしていました。しかし、それは1つの空のタグを残します。私はremovechildプロパティを使って削除することができました。

しかし、毎回内容を追加することができません。

どのように達成するには?

答えて

2

ログファイルにXMLを使用することは悪いアプローチです。特に、ログファイルが大きくなるとコストが高くなります。もっと下に。

ソリューション:

$file = Resolve-Path 'logfile.xml' 
$output = [xml](Get-Content $file) 
$vmNode = $output.DocumentElement 

$newNode = [xml]@" 
    <VM> 
    <VMName>Fresh_R2VM</VMName> 
    <AccessedBy>David</AccessedBy> 
    <AccessedDate>$([DateTime]::Today)</AccessedDate> 
    <AccessedTime>$([DateTime]::Now.ToString('HH:mm:ss'))</AccessedTime> 
    </VM> 
"@ 

# Need to move the VM node from document newNode to the output document 
$newNode = $output.ImportNode($newNode.DocumentElement, $true) 
$vmNode.appendChild($newNode) | out-null 

$output.Save($file) 

パフォーマンス:たびに、これはそれをロードし、完全にその後、一つのノードを追加するために、既存の文書を解析し、新しいノードを追加し、文書全体を保存します。各追加は、前のものよりも長くかかります。数千のノードでは、これは重要なことであり、数十万もあります。解析されたXMLは大きなメモリオーバーヘッドになり始めます。XmlDocument重要でないXMLドキュメントを表すオブジェクトは、多くの領域を必要とします。

代替

  1. テキストファイルを使用してください。新しいデータだけが最後に直接書き込まれます(ファイルを開いて、書き込み位置を終了して書き込みます)。これはファイルサイズの低下がないことを示し、メガバイトのコンテンツを持つファイルは、新しいキロバイトのファイルと同じくらい速く追加されたデータを持つことができます。さらに、ファイルを検索するツール(PowerShellのSelect-Stringなど)は、ファイルを段階的に処理することができます(ファイル全体を読み込む必要はありません)。

  2. これはハックの何かです:DTDとXMLエンティティを使用します。 LogFile.xmlには、LogFileContent.xml-dataを参照する外部エンティティを定義するDTDが含まれています。 <VirtualMachines>ノードがLogFile.xmlの場合、そのエンティティを使用してLogFileContent.xml-dataをその子としてインポートします。つまり、LogFileContent.xml-dataは有効なドキュメントである必要はありません(ルート要素は必要ありません)。 これは、処理するツールのどれもがそのDTDを処理する必要があることを意味します(例:.NET、したがってPowerShell、XMLサポートはデフォルトで外部エンティティを無効にします)。

+0

ガイダンスバディありがとう。テキストファイルをログファイルとして使用することに決めました。 – Samselvaprabu

+0

オルタナティブ2は何年も私のために非常にうまくいっています。 –

+0

私は選択肢2に興味があります。誰かが良い例と説明にリンクしていますか?ありがとうございます –

関連する問題