2014-11-08 1 views
6

Ho un XML di una coppia di gigabyte. Non ci sono spazi nell'XML.Come posso utilizzare XmlReader in PowerShell per lo streaming di file XML grandi/enormi?

così ho scritto un po 'di codice C# per dividere in file singoli (che ha qualche codice aggiuntivo per eseguire alcune cose per esempio randomizzazione durante il test)

using (XmlReader MyReader = XmlReader.Create(@"d:\xml\test.xml")) 
      { 
       while (MyReader.Read()) 
       { 
        switch (MyReader.NodeType) 
        { 
         case XmlNodeType.Element: 
          if (MyReader.Name == "Customer") 
          { 
           XElement el = XElement.ReadFrom(MyReader) as XElement; 
           if (el != null) 
           { 
            custNumber = (string)el.Element("CustNumber"); 
            output = @"d:\xml\output\" + custNumber; 

            File.WriteAllText(output, el.ToString()); 
           }          
          } 
          break; 
        } 
       } 
      } 

ho quindi analizzare i file risultanti con PowerShell, fondamentalmente perché ho trovare più facile lavorare con il server mentre le specifiche possono cambiare e posso cambiare lo script al volo.

Quindi ... qual è il modo più semplice per convertire quanto sopra anche in PowerShell, mettendo [.Net qui] prima di tutto? dovrei leggere byte per byte solo nel caso in cui abbia "<cust" su una riga e "omer>" nella successiva?

risposta

8

Questo dovrebbe essere abbastanza vicino a quello che si voleva fare in PowerShell:

$f = [System.Xml.XmlReader]::create("d:\xml\test.xml") 

while ($f.read()) 
{ 
    switch ($f.NodeType) 
    { 
     ([System.Xml.XmlNodeType]::Element) # Make sure to put this between brackets 
     { 
      if ($f.Name -eq "Customer") 
      { 
       $e = [System.Xml.Linq.XElement]::ReadFrom($f) 

       if ($e -ne $null) 
       { 
        $custNumber = [string] $e.Element("CustNumber") 

        $e.ToString() | Out-File -Append -FilePath ("d:\xml\output\"+$e.ToString()) 
       } 
      } 
      break 
     } 
    } 
} 
+0

dovuto spostare il passaggio a un if ($ f.NodeType eq [Syste ,,,) ed è interessante notare in PowerShell aveva da usare. Valore dell'elemento contrario a C#. – edelwater

+1

@edelwater: l'aggiunta di parentesi attorno all'opzione interruttore lo ha risolto. – Wouter