Home > other >  How to fetch an attribute value from xml using powershell and replace with string content
How to fetch an attribute value from xml using powershell and replace with string content

Time:01-26

<?xml version="1.0" encoding="UTF-8"?>
<abc>
   <myTask id="MyBatchExport" name="MyBatchExport" scriptFormat="javascript">
      <task><![CDATA[var requestItemsParm= execution.getVariable("requestItems");
      var requestItemsParm= JSON.parse(requestItemsParm);
      var batchExport = {};]]></task>
   </myTask>
   <myTask id="MyBatchImport" name="MyBatchImport" scriptFormat="javascript">
      <task><![CDATA[var requestItemsParm= execution.getVariable("requestItems");
      var requestItemsParm= JSON.parse(requestItemsParm);
      var batchImport = {};]]></task>
   </myTask>
</abc>

Based on the Mytask tag id value, have to replace the task data with other string content using powershell

$xmldata = [xml](Get-Content test1.xml);
$StrContent = "my own content to replace in between CDATA"
$taskdata= $xmldata.abc.myTask.task

with above assignment, i can get all task data as array. But i want to task tag value if id is equal to "MyBatchImport" or "MyBatchExport" or some "xyz"

Can someone help me here

CodePudding user response:

PowerShell has a nice feature called Member Enumeration which might come at hand when reading properties:

$xmldata.abc.myTask.task |Get-Member

   TypeName: System.Xml.XmlElement

Name                 MemberType            Definition
----                 ----------            ----------
ToString             CodeMethod            static string XmlNode(psobject instance)
...
WriteTo              Method                void WriteTo(System.Xml.XmlWriter w)
Item                 ParameterizedProperty System.Xml.XmlElement Item(string name) {get;}, System.Xml.XmlElement Item(string localname, string ns) {get;}
#cdata-section       Property              string #cdata-section {get;set;}

But it might get confusing when you want to write data because you will need to be specific in the node branch you want to write (as it would be incorrect to write to all branches in once).

In this specific case the branche is at the $xmldata.abc.myTask:

                     ┌─ [0].task.'#cdata-section'
$xmldata.abc.myTask ─┤
                     └─ [1].task.'#cdata-section'

So you will need to define whether you want to change the first or the second mytask. In case you want to replace the first mytask (in the zero based array):

$xmldata.abc.myTask[0].task.'#cdata-section' = $StrContent
$xmldata.Save([Console]::Out)

<?xml version="1.0" encoding="ibm850"?>
<abc>
  <myTask id="MyBatchExport" name="MyBatchExport" scriptFormat="javascript">
    <task><![CDATA[my own content to replace in between CDATA]]></task>
  </myTask>
  <myTask id="MyBatchImport" name="MyBatchImport" scriptFormat="javascript">
    <task><![CDATA[var requestItemsParm= execution.getVariable("requestItems");
      var requestItemsParm= JSON.parse(requestItemsParm);
      var batchImport = {};]]></task>
  </myTask>
</abc>

CodePudding user response:

To resolve a set of nodes based on some condition relating to their parent nodes, XPath is usually the right tool for the job.

For example, to get the CDATA section under only those <task> nodes whose parents are <myTask> with a name attribute value of MyBatchExport, you could use the following expression:

$targetNodes = $xmldata.SelectNodes('//myTask[@name = "MyBatchExport"]/task/text()')

Then simply loop over each resolved node and update the contents:

$targetTaskNodes |ForEach-Object { $_.InnerText = $StrContent }
  •  Tags:  
  • Related