Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I alter XML with PowerShell/XPath and save the document?

I'm looking to use PowerShell to alter XML. I haven't been able to copy XML using XPath. I can load the XML, but I can't figure out how to list the XML with an XPath and create another XML file with what I retrieve.

$doc = new-object "System.Xml.XmlDocument"
$doc.Load("XmlPath.xml")

Also, how would you add the removed XML to another XML file?

like image 910
Bruce227 Avatar asked Nov 12 '09 02:11

Bruce227


People also ask

How do I update XML attributes in PowerShell?

To update the specific XML node using PowerShell, we first need to select that node with the attribute with SelectSingleNode() method. We have below the XML file from the link stored in SampleXml. XML on C:\Temp location. The above commands will load the XML file and select node with attribute value 'bk102'.

How do I get the contents of a XML file in PowerShell?

One way to read an XML document in PowerShell is to typecast a variable to the type [xml]. To create this variable, we can use the Get-Content cmdlet to read all of the text in an XML document. To typecast the output of Get-Content we can simply prepend the text [xml] before the variable.


2 Answers

If you're using PowerShell 2.0 you can use the new Select-Xml cmdlet to select xml based on an XPath expression e.g.:

$xml = '<doc><books><book title="foo"/></books></doc>'
$xml | Select-Xml '//book'
Node    Path          Pattern
----    ----          -------
book    InputStream   //book

To remove nodes:

PS> $xml =[xml]'<doc><books><book title="foo"/><book title="bar"/></books></doc>'
PS> $xml | Select-Xml -XPath '//book' | 
        Foreach {$_.Node.ParentNode.RemoveChild($_.Node)}

title
-----
foo
bar

PS> $xml.OuterXml
<doc><books></books></doc>

Then to save to file:

$xml.Save("$pwd\foo.xml")
Get-Content foo.xml
<doc>
  <books>
  </books>
</doc>
like image 156
Keith Hill Avatar answered Oct 22 '22 01:10

Keith Hill


Load Linq Xml assemblies:

[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq")
[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.XPath")

Load your xml (Note, you can use ::Load("file") instead of ::Parse(...) to load from file:

$xml = [System.Xml.Linq.XDocument]::Parse("<root> <row>Hey</row> <row>you</row> </root>")

Modify (in this case Remove the first row:

[System.Xml.XPath.Extensions]::XPathSelectElement($xml, "//row").Remove()

Save to file:

$xml.Save("MyXml.xml")

Using System.Xml (instead of System.Xml.Linq):

$doc = new-object "System.Xml.XmlDocument"
$doc.Load("MyXml_int.xml")

$node = $doc.SelectSingleNode("//row");
$node.ParentNode.RemoveChild($node)

$doc.Save("MyXml_out.xml")
like image 2
Nestor Avatar answered Oct 22 '22 03:10

Nestor