0

I need for my job to update a xml file from user data inputs.

Problem summary :

After 1 complete day of trials, I did not succeed to create a PowerShell function allowing me to insert as much as I want "dependency" element under the "dependencies" element from the user's data. Same for "prerequisite" under the "prerequisites" element.

My researchers :

add multi level xml powershell adding XML sub-elements

My most promising code :

```
# load XML file
[xml]$doc = Get-Content "D:\TEMP\INPUT.xml"


# create node <Dependency>
$sref = $doc.CreateNode('element', 'Dependency', '')
$sref.SetAttribute("id", "GGG")
$sref.SetAttribute("version", "HHH")

# create node <Dependencies> and append child nodes <id> and <version>
$src = $doc.CreateNode('element', 'Dependencies', '')
#$src.AppendChild($comp)
$src.AppendChild($sref)

# append node <Source> to node <metadata>
$svc = $doc.SelectSingleNode('//metadata')
$svc.AppendChild($src)

# save XML file
$doc.Save("D:\TEMP\OUTPUT.xml")
```

My original xml file :

```
<?xml version="1.0" encoding="utf-8"?>
<package>
    <metadata>
        <id>AAA</id>
        <version>BBB</version>
        <authors>CCC</authors>
        <owners>XXX</owners>
        <description>EEE</description>
        <keyfile>DDD</keyfile>
        <dependencies />
        <prerequisites />
        <librairies />
        <rules />
    </metadata>
    <files />
</package>
```

Expected XML file :

```
<?xml version="1.0" encoding="utf-8"?>
<package>
  <metadata>
    <id>AAA</id>
    <version>BBB</version>
    <authors>CCC</authors>
    <owners>XXX</owners>
    <description>EEE</description>
    <keyfile>DDD</keyfile>
    <dependencies>
      <dependency id="GGG" version="HHH" />
      <dependency id="III" version="JJJ" />
      <dependency id="KKK" version="LLL" />
    </dependencies>
    <prerequisites>
      <dependency id="UUU" version="VVV" />
      <dependency id="WWW" version="XXX" />
    </prerequisites>
    <librairies />
    <rules />
  </metadata>
  <files />
</package>
```

User data inputs :

```
For "dependency" :
   - Parameter set 1 :
      - GGG
      - HHH
   - Parameter set 2 :
      - III
      - JJJ
   - Parameter set 3 :
      - KKK
      - LLL

For "prerequisite" :
   - Parameter set 1 :
      - UUU
      - VVV
   - Parameter set 2 :
      - WWW
      - XXX
```
neuvidor
  • 1
  • 1

1 Answers1

0

You were pretty close, but you don't need to create your own <dependencies> element - you just need to get a reference to the one in your original document...

$doc = [xml] @"
<?xml version="1.0" encoding="utf-8"?>
<package>
  <metadata>
    <id>AAA</id>
    <version>BBB</version>
    <authors>CCC</authors>
    <owners>XXX</owners>
    <description>EEE</description>
    <keyfile>DDD</keyfile>
    <dependencies />
    <prerequisites />
    <librairies />
    <rules />
  </metadata>
  <files />
</package>
"@;

# create new "<dependency>" element
$dependency = $doc.CreateNode("element", "dependency", "");
$dependency.SetAttribute("id", "GGG");
$dependency.SetAttribute("version", "HHH");

# add it to the existing "<dependencies>" element
$dependencies = $doc.SelectSingleNode("package/metadata/dependencies");
$dependencies.AppendChild($dependency);

# save XML file
$doc.Save("D:\TEMP\OUTPUT.xml")
# <?xml version="1.0" encoding="utf-8"?><package><metadata><id>AAA</id><version>BBB</version><authors>CCC</authors><owners>XXX</owners><description>EEE</description><keyfile>DDD</keyfile><dependencies><dependency id="GGG" version="HHH" /></dependencies><prerequisites /><librairies /><rules /></metadata><files /></package>

If you want pretty-printed xml with line breaks and indents you can do this to save the xml instead:

# see https://devblogs.microsoft.com/powershell/format-xml/
function Format-XML ([xml]$xml, $indent=2)
{
    $StringWriter = New-Object System.IO.StringWriter
    $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter
    $xmlWriter.Formatting = "indented"
    $xmlWriter.Indentation = $Indent
    $xml.WriteContentTo($XmlWriter)
    $XmlWriter.Flush()
    $StringWriter.Flush()
    Write-Output $StringWriter.ToString()
}

Set-Content -Path "D:\TEMP\OUTPUT.xml" -Value (Format-XML $doc);

#<?xml version="1.0" encoding="utf-8"?>
#<package>
#  <metadata>
#    <id>AAA</id>
#    <version>BBB</version>
#    <authors>CCC</authors>
#    <owners>XXX</owners>
#    <description>EEE</description>
#    <keyfile>DDD</keyfile>
#    <dependencies>
#      <dependency id="GGG" version="HHH" />
#    </dependencies>
#    <prerequisites />
#    <librairies />
#    <rules />
#  </metadata>
#  <files />
#</package>
mclayton
  • 8,025
  • 2
  • 21
  • 26