2012-01-05 5 views
1

私はレジストリから読み込んで変更したいデータがあります。例のデータは次のようになります。ハッシュテーブルまたはオブジェクトとしてのデータの読み取り/変更

<User Blob> 
    <Item> 
     <Key>SomeKey</Key> 
     <Value>false</Value> 
    </Item> 
    <Item> 
     <Key>AnotherKey</Key> 
     <Value></Value> 
    </Item> 
</User Blob> 
<Primary Server Blob> 
    <Item> 
     <Key>Just a key</Key> 
     <Value></Value> 
    </Item> 
    <Item> 
     <Key>And another key</Key> 
     <Value>true</Value> 
    </Item> 
</Primary Server Blob> 

特定のキーの値を変更できます。例:

User Blob.SomeKey = $true 

データをXMLまたはHashTableにキャストしようとしましたが、これはエラーです。

+0

そこにあるものの周りにルートタグを追加すると、xmlとして扱うことができるはずです。 – EBGreen

+1

あなたはまたあなたのタグのスペースを取り除きたいかもしれません –

+0

@jon Z:はいスペースはそれを解析する際に問題と思われる...しかし、次の問題は2つのルート要素があるということです? – Remko

答えて

1

を追加してください。大量のオブジェクトをメモリにロードするのを避けるため)、ある種のドキュメントを使用したいと思うでしょう。 XPathを利用できるため、XmlDocumentをお勧めします。 (XPathはこの種の問題を単純にしています。)

正しいことを指摘しておきますが、単一のXMLルートが必要です。これは簡単に解決できます。データを別のルートノードにラップするだけです。

だからトリックを行うべきいくつかのコードがあります。

$data = @" 
<UserBlob> 
    <Item> 
     <Key>SomeKey</Key> 
     <Value>false</Value> 
    </Item> 
    <Item> 
     <Key>AnotherKey</Key> 
     <Value></Value> 
    </Item> 
</UserBlob> 
<PrimaryServerBlob> 
    <Item> 
     <Key>Just a key</Key> 
     <Value></Value> 
    </Item> 
    <Item> 
     <Key>And another key</Key> 
     <Value>true</Value> 
    </Item> 
</PrimaryServerBlob> 
"@ 

$wrappedData = "<root>$data</root>" 
$doc = new-object Xml.XmlDocument 
$doc.LoadXml($wrappedData) 
$nodeToChange = $doc.SelectSingleNode("/root/UserBlob/Item[Key='SomeKey']") 
if($nodeToChange){ 
    $nodeToChange.Value = "NEW VALUE" 
} 
$doc.Save("[PATH_TO_OUTPUT_FILE]") 

私はエラー処理を省略し、簡潔にするためにオブジェクトの処分を修正しました。私はそれをあなたに任せます。 :-)

XmlDocumentの詳細については、documentationを参照してください。

UPDATE

再び追加のルートドキュメントを削除するには、単なる文字列としてそれを得るためにこれを使用します。

$newWrappedData = $doc.Root.InnerXml 

次に、StreamWriterまたはFile.CreateTextなどを使用して文字列を保存します。

+0

+1です。保存する前に追加したルートノードを削除する必要があると思いますか? – Remko

+0

ノードをラップせずにxmlを取得する方法を示すためのアップデートを追加しました。 – Richard

1

以下のコードで動作するようにしましたが、ConformanceLevel to Fragmentの設定で複数のルート要素を処理できるため、XMLReaderを使用しています。よりよい解決策がある場合は、あなたが(ちょうど読んでいない)変更したいXMLデータを持っており、データは(小十分なサイズである場合、一般的に...答えとして

$readerSettings = New-Object System.Xml.XmlReaderSettings 
$readerSettings.ConformanceLevel = [System.Xml.ConformanceLevel]::Fragment 

$reader = [system.Xml.XmlReader]::Create("MyXML.xml", $readerSettings) 
while ($reader.Read()) 
{ 
    switch ($reader.NodeType) 
    { 
     "Element" 
     { 
      $numAttributes = $reader.AttributeCount 
      $nodeName = $reader.Name 
      "nodeName = {0}" -f $nodeName 
      for ($i = 0 ; $i -lt $numAttributes ; $i++) 
      { 
       $attributeValue = $reader.GetAttribute($i) 
       "`tattributeValue = {0}" -f $attributeValue 
      } 

      break 
     } 
     "Text" 
     { 
      $xmlNodeText = $reader.Value 
      "`txmlNodeText = {0}" -f $xmlNodeText 
      break 
     } 
     "EndElement" 
     { 
      $xmlNodeText = [String]::Empty 
      break 
     } 

    default { break } 
    } 
} 
関連する問題