Reputation: 396
I need some assistance building up a XML-file with Powershell. I have never done this before.
At the beginning I felt lucky and tried "Export-Clixml", but it doesn't produce output as I would want to have. I need clean XML.
I have an existing XML-File, which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
</DeploymentScript>
I read out the settings from XML and do some stuff in Powershell. I create an object, which looks like this:
TaskSequenceNumber TaskSequenceName
------------------ ----------------
0 01_Base
1 02_XA
I want to save this object in my XML-file. (append) The XML-file should finally look like this:
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
<Deploy>
<SequenceData>
<TaskSequenceNumber>1</TaskSequenceNumber>
<TaskSequenceName>01_Base</TaskSequenceName>
</SequenceData>
<SequenceData>
<TaskSequenceNumber>2</TaskSequenceNumber>
<TaskSequenceName>02_XA</TaskSequenceName>
</SequenceData>
</Deploy>
</DeploymentScript>
I have tried some .NET XML methods, but I didn't get a result. Would anybody give me an example on how to do this?
.
EDIT: Thanks to "Frode F."! Here the latest code:
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
</DeploymentScript>
"@
#$xml = [xml]( Get-Content -Path "$env:USERPROFILE\Desktop\Deploy-Settings.xml" )
$TaskSequences = [pscustomobject]@{TaskSequenceNumber=0;TaskSequenceName="01_Base"},[pscustomobject]@{TaskSequenceNumber=1;TaskSequenceName="02_XA"}
#Add Deploy-node
$DeployNode = $xml.CreateElement( "Deploy" )
$xml.DeploymentScript.AppendChild( $DeployNode ) > $null
foreach ( $element in $TaskSequences ) {
$SeqDataNode = ([xml]@"
<SequenceData>
<TaskSequenceNumber>$($element.TaskSequenceNumber + 1)</TaskSequenceNumber>
<TaskSequenceName>$($element.TaskSequenceName)</TaskSequenceName>
</SequenceData>
"@).FirstChild
#Add to Deploy-node
$DeployNode.AppendChild( $xml.ImportNode( $SeqDataNode,$true ) ) > $null
}
$xml.Save( "$env:USERPROFILE\Desktop\Test.xml" )
Upvotes: 0
Views: 867
Reputation: 54891
You could try something like this by using xml-classes in .NET:
#SampleInput
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<Settings>
...
</Settings>
"@
$TaskSequences = [pscustomobject]@{TaskSequenceNumber=0;TaskSequenceName="01_Base"},[pscustomobject]@{TaskSequenceNumber=1;TaskSequenceName="02_XA"}
#$xml = [xml](Get-Content -Path InputFile.xml)
#$TaskSequences = Get-RealDataFromSomeWhere
#Create new xml and remove root node
$newxml = $xml.Clone()
$newxml.RemoveChild($newxml.SelectSingleNode("/Settings")) > $null
#Add new DeploymentScript root-node with copy of Settings
$DeploymentScriptNode = $newxml.CreateElement("DeploymentScript")
$DeploymentScriptNode.AppendChild($newxml.ImportNode($xml.SelectSingleNode("/Settings"),$true)) > $null
$newxml.AppendChild($DeploymentScriptNode) > $null
#Add Deploy-node
$DeployNode = $newxml.CreateElement("Deploy")
$DeploymentScriptNode.AppendChild($DeployNode) > $null
foreach ($ts in $TaskSequences) {
#Create SequenceData-element per TS
$SeqDataNode = $newxml.CreateElement("SequenceData")
$SeqDataNode.AppendChild($newxml.CreateElement("TaskSequenceNumber")) > $null
$SeqDataNode.AppendChild($newxml.CreateElement("TaskSequenceName")) > $null
$SeqDataNode.TaskSequenceNumber = "$($ts.TaskSequenceNumber + 1)"
$SeqDataNode.TaskSequenceName = $ts.TaskSequenceName
#Add to Deploy-node
$DeployNode.AppendChild($SeqDataNode) > $null
}
$newxml.Save("$env:USERPROFILE\Desktop\Test.xml")
Or the messy, but shorter, string method:
#SampleInput
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<Settings>
...
</Settings>
"@
$TaskSequences = [pscustomobject]@{TaskSequenceNumber=0;TaskSequenceName="01_Base"},[pscustomobject]@{TaskSequenceNumber=1;TaskSequenceName="02_XA"}
#$xml = [xml](Get-Content -Path InputFile.xml)
#$TaskSequences = Get-RealDataFromSomeWhere
#Create new xml and remove root node
$newxml = [xml]@"
$($xml.FirstChild | ? { $_.NodeType -eq 'XmlDeclaration' } | % { $_.OuterXml })
<DeploymentScript>
$($xml.SelectSingleNode("/Settings").OuterXml)
<Deploy>
$($TaskSequences | % {
"<SequenceData>
<TaskSequenceNumber>$($_.TaskSequenceNumber + 1)</TaskSequenceNumber>
<TaskSequenceName>$($_.TaskSequenceName)</TaskSequenceName>
</SequenceData>" })
</Deploy>
</DeploymentScript>
"@
$newxml.Save("$env:USERPROFILE\Desktop\Test.xml")
Test.xml:
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
<Deploy>
<SequenceData>
<TaskSequenceNumber>1</TaskSequenceNumber>
<TaskSequenceName>01_Base</TaskSequenceName>
</SequenceData>
<SequenceData>
<TaskSequenceNumber>2</TaskSequenceNumber>
<TaskSequenceName>02_XA</TaskSequenceName>
</SequenceData>
</Deploy>
</DeploymentScript>
Upvotes: 2