Reputation: 65
<?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
Upvotes: 0
Views: 192
Reputation: 174445
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 }
Upvotes: 1
Reputation: 23623
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>
Upvotes: 1