So, I'm writing a script to do some simple xmlrpc requests. As far as I can tell Powershell doesn't have anything built in, so the best and simplest solution I've found is to simply create the xml and post it using invoke-webrequest or invoke-restmethod.
If someone knows of a better way with out of the box functionality, feel free to educate me.
Now, here's the part I'm having some trouble with. Generating the xml. How I would like it to work: create a custom object, add properties, convert to xml and post. Even better would be to create an xml-object, add nodes and properties and then post it.
This appears to be a bit of a PITA though, and at this point I feel it will be easier to treat the xml as a string in Powershell and edit/manage it that way. So, am I missing something or is working with xml in Powershell not as easy as I had hoped?
Edit: To clarify, I'm asking for the best tool/technique to create custom xml in Powershell. So far my impression is that the best way is to simply build it as a string, as using the built in xml tools is cumbersume and messy. However I realize this would not be viable for larger or more complex XML-structures.
What I have so far, which doesn't work and isn't as pretty as I'd like. This code gives me the following error
Method invocation failed because [System.String] does not contain a method named 'Appendchild'.
$xmlreq = [xml]@'
<?xml version="1.0"?>
<methodCall>
<methodName>methodname</methodName>
</methodCall>
'@
$child = $xmlreq.CreateElement("params")
$xmlreq.methodCall.Appendchild($child)
$child = $xmlreq.CreateElement("param")
$xmlreq.methodCall.params.Appendchild($child)
$child = $xmlreq.CreateElement("value")
$xmlreq.methodCall.params.param.Appendchild($child)
$child = $xmlreq.CreateElement("string")
$xmlreq.methodCall.params.param.value.Appendchild($child)
$xmlreq.methodCall.params.param.value.string = "value"
What the resulting XML should look like:
<?xml version="1.0"?>
<methodCall>
<methodName>methodname</methodName>
<params>
<param>
<value>
<string>param1</string>
</value>
</param>
<param>
<value>
<string>param2</string>
</value>
</param>
<param>
<value>
<string>param3</string>
</value>
</param>
<param>
<value>
<string>param4</string>
</value>
</param>
<param>
<value>
<struct>
<member>
<name>property1</name>
<value>
<int>0</int>
</value>
</member>
<member>
<name>property2</name>
<value>
<string>value</string>
</value>
</member>
<member>
<name>property3</name>
<value>
<int>1</int>
</value>
</member>
<member>
<name>property4</name>
<value>
<string>value</string>
</value>
</member>
<member>
<name>property5</name>
<value>
<int>2</int>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
Try something like this to build your tree:
[xml]$doc = @'
<?xml version="1.0"?>
<methodCall>
<methodName>methodname</methodName>
</methodCall>
'@
$node1 = $doc.CreateElement('params')
$node2 = $doc.CreateElement('param')
$node3 = $doc.CreateElement('value')
$node4 = $doc.CreateElement('string')
$node4.set_innertext('param1')
$node3.AppendChild($node4)
$node2.AppendChild($node3)
$node1.AppendChild($node2)
$node2 = $doc.CreateElement('param')
$node3 = $doc.CreateElement('value')
$node4 = $doc.CreateElement('string')
$node4.set_innertext('param2')
$node3.AppendChild($node4)
$node2.AppendChild($node3)
$node1.AppendChild($node2)
$doc.methodCall.AppendChild($node1)
$doc.Save("$(pwd)\foo.xml")
cat .\foo.xml
This is just a quick and dirty example to demonstrate a point. You'll need to polish this up for your needs. I did the following:
xml
type declaration to the variable and not the string.Hope this helps!