Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell System.Xml.XmlElement but I use System.Xml.XmlDocument?

Tags:

powershell

xml

I keep getting the following exception in my PowerShell script:

Method invocation failed because [System.Xml.XmlElement] does not contain a method named CreateElement'.

But as far as I know I am using System.Xml.XmlDocument? https://msdn.microsoft.com/en-us/library/fw1ys7w6(v=vs.110).aspx

What am I doing wrong?

$file = "file.xml"
$xmlDoc = [System.Xml.XmlDocument](Get-Content $file)

if ($xmlDoc) {
    $xmlDoc.layout.nodes.SetAttribute("environment", "develop"); #this works

    $newNode = $xmlDoc.layout.nodes.CreateElement("Node")
    $newNode.SetAttribute("name", "Hello world")

    $xmlDoc.AppendChild($newNode)

    $xmlDoc.Save($systemConfigFile)
}

The XML file is before I launch this script:

<layout>
    <nodes enviroment="[uknown]">
    </nodes>
</layout>

I expect the outcome te become:

<layout>
    <nodes enviroment="develop">
        <node name="Hello world" />
    </nodes>
</layout>
like image 575
StuiterSlurf Avatar asked Dec 23 '22 12:12

StuiterSlurf


2 Answers

Let's look at this line:

$xmlDoc.layout.nodes.CreateElement("Node")

This is calling the method CreateElement(...) on the object $xmlDoc.layout.nodes. We could break it into two lines like this:

$something = $xmlDoc.layout.nodes
$something.CreateElement("Node")

We know that $xmlDoc is a System.Xml.XmlDocument object, but what type of object is $something? It doesn't refer to the whole document, it refers to the <nodes> element. From the error message, we learn that it is in fact a System.Xml.XmlElement object.

A few lines down, you make the opposite error: you call AppendChild on $xmldoc, when actually you want to append it to the specific element.

So, first we need to use $xmlDoc to create the new element; then we can use $xmlDoc.layout.nodes (which I called earlier $something) to say where we want to put the new element:

$newNode = $xmlDoc.CreateElement("Node")
$newNode.SetAttribute("name", "Hello world")

$xmlDoc.layout.nodes.AppendChild($newNode)
like image 160
IMSoP Avatar answered Mar 24 '23 18:03

IMSoP


To set a new node you have to declare a new node in the XML layout with CreateNode() and append this node to the parent node like this :

$file = "file.xml"
[xml]$xmlDoc = [System.Xml.XmlDocument](Get-Content $file)

if ($xmlDoc) {
    $xmlDoc.layout.nodes.SetAttribute("environment", "develop")

    #part that adds new node
    $secNode = $xmlDoc.CreateNode("element","node",$null)
    $secNode.SetAttribute("Name","Hello world") | Out-Null
    $xmlDoc.layout.nodes.AppendChild($secNode) | Out-Null
}

$xmlDoc.Save($file)

Returns :

<?xml version="1.0" encoding="UTF-8"?>
<layout>
  <nodes environment="develop">
    <node Name="Hello World" />
  </nodes>
</layout>
like image 31
Manu Avatar answered Mar 24 '23 17:03

Manu