0

I have a PowerShell script that I use to remove certain tags from a XML file:

$Output = "C:\Users\Desktop\Resulttask.xml"

# Load the existing document
$Doc = [xml](Get-Content -Path C:\Users\Desktop\Test.xml)

# Specify tag names to delete and then find them
$DeleteNames = "Total" | ForEach-Object { 
    $Doc.ChildNodes.SelectNodes($_)
} | ForEach-Object {
    $Doc.ChildNodes.RemoveChild($_)
}

$Doc.Save($Output)

My problem is that it work with a standard XML file like for example:

<html>
<body>b</body>
<Price>300</Price>
<Total>5000</Total>
</html>

But the problem is that the XML file is has to remove the tags from contains multiple prefixes like.

<ns:html xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="2" release="1">
  <ns:body>b</ns:body>
  <ns:Price>300</ns:Price>
  <ns:Total>5000</ns:Total>
</ns:html>

Then it does not remove the tag but is get a error as following

Exception calling "SelectNodes" with "1" argument(s): "Namespace Mangager or
XSltContext needed. This query has a prefix, variable, or user-defined function."
At line:2  char:5
+     $Doc.ChildNodes.SelectNodes($_)
+     -------------------------------
    + CategoryInfo           : NotSpecified: (:) [], MethodInvocationExeption
    + FullyQuallifiedErrorId : DotNetMethodException

Error message in Powershell

My question is how do I ensure that the PowerShell command ignores the prefix ns:.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
Jarno343
  • 91
  • 1
  • 7
  • 1
    You can't ignore it as it's part of the XML data. Besides, the error message already tells you what you need to do: use a [namespace manager](http://stackoverflow.com/a/35653697/1630171). – Ansgar Wiechers Sep 06 '16 at 08:19

1 Answers1

0

Try this.

It will remove all nodes machting the input values.

# input is an array of values to delete
param([String[]] $values)

# Load the existing document
$xml = [xml](Get-Content -Path  D:\Temp\newtask.xml)

# Loop throug the input list
foreach ($value in $values) {

    # Set the namespace prefix
    $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
    $ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI)

    # Get all nodes matching the input value
    $nodes =  $xml.SelectNodes("//*") | Where-Object { ($_.Name -eq "$value")}

    # in case there are multiple nodes matching the input value
    foreach ($node in $nodes )  {

        # Move to the parent node to remove the child.
        $node.ParentNode.RemoveChild($node)
    }
}

# Save the result in a different file so you can compare the files.
$filename = 'D:\Temp\newtask_result.xml'
$xml.save($filename)

Call the script like this

PS D:\temp> .\RemoveXmlElement.ps1 -values ns:Price,ns:Total
Jeroen
  • 16
  • 4