Home > Back-end >  Removing xml attributes from a element
Removing xml attributes from a element

Time:07-29

I have been trying to solve this unique challenge that is giving with much problems than I would've expected. So, here is a snippet of the XML result output that I get from the SOAP server:

<ns2:getReportResultResponse xmlns:ns2="http://service.admin.ws.example.com/">
  <return>
    <header>
      <values>
        <data>DATE</data>
        <data>AGENT</data>
        <data>AGENT FIRST NAME</data>
        <data>AGENT LAST NAME</data>
        <data>CALLS count</data>
        <data>HANDLE TIME</data>
        <data>AFTER CALL WORK TIME</data>
        <data>CONFERENCE TIME</data>
        <data>SHORT CALLS count</data>
        <data>LONG CALLS count</data>
      </values>
    </header>
    <records>
      <values>
        <data>2022/07/27</data>
        <data>[email protected]</data>
        <data>Test</data>
        <data>User</data>
        <data>49</data>
        <data>02:00:00</data>
        <data>00:45:00</data>
        <data xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
        <data>49</data>
        <data>0</data>
      </values>
    </records>
  </return>
</ns2:getReportResultResponse>

How can I do with removing the xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" attributes from the data element in order to process the data correctly? I tried multiple methods like Select-Xml and it works for most of the elements BUT the ones with the attributes.

For context of my PowerShell code:

Select-Xml -Content ([xml]$final_response | Select-Object -ExpandProperty Objects | Select-Object -ExpandProperty Object | Select-Object -ExpandProperty '#text') "//return/*/values" -Namespace @{ ns = 'http://service.admin.ws.example.com/'} |
  ForEach-Object {
    # See if an entry already exists for the key at hand.
    if ($obj.Contains($_.Node.header.values.data)) {
      # Convert the entry value into an array on demand and 
      # append the value at hand.
      [array] $obj[$_.Node.header.values.data]  = $_.Node.records.values.data
    }
    else {
      # Create the entry, using the value as-is.
      $obj[$_.Node.header.values.data] = $_.Node.records.values.data
    }
  }

This snippet came from one of the answers to the question I made in the past.

Is there a way to come around this?

P.S. The $final_response is the first code snippet output.

CodePudding user response:

A simplified response, showing only the issue of removing the namespace attributes.

[Xml]$xml = @" 
[your xml above]
@ 

#declare the relevant namespace
$ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) 
$ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")

#select your target element
$node = $xml.SelectSingleNode('//records/values//data[@xsi:nil]',$ns) 

#and get rid of those attributes..
$node.RemoveAttribute('xsi:nil') 
$node.RemoveAttribute('xmlns:xsi') 

echo $xml.OuterXml

The output should be your expected output.

  • Related