1

I'm trying to create some multi level xml in powershell. I started with the code from

adding XML sub-elements

I'm having trouble getting my head around how to create a second sublevel. An example of the xml I want to create is below.

Thanks in advance,

Goldstien

<?xml version="1.0" ?>
<!DOCTYPE svcengine SYSTEM "service.dtd">

<Services>

<Service>
<Name>My service</Name>
<Label>Availability</Label>
<Source>
    <Composition/>
    <ServiceRef>My service ref</ServiceRef>
</Source>
</Service>

</Services>
Community
  • 1
  • 1
Goldstien
  • 13
  • 4
  • I'm not sure what you mean by "create a second sublevel". Do you want to modify the structure? For that you'd have to change the DTD. Or do you just want to append a child node to some node? That would be done like this (in general): select a node, create a new element, append the new element to the selected node. – Ansgar Wiechers Feb 25 '13 at 18:34
  • So within the Service tag are the source tag and children. I am having trouble adapting the code from the previous post to produce that xml code above. I'm familiar with powershell but new to xml coding. – Goldstien Feb 26 '13 at 08:18

1 Answers1

2

If you have a structure like this:

<Services>
  <Service>
    <Name>My service</Name>
    <Label>Availability</Label>
  </Service>
</Services>

and want to add a node <Source> so that it looks like this:

<Services>
  <Service>
    <Name>My service</Name>
    <Label>Availability</Label>
    <Source>
      <Composition/>
      <ServiceRef>My service ref</ServiceRef>
    </Source>
  </Service>
</Services>

you could go about it like this:

# load XML file
[xml]$doc = Get-Content "C:\service.xml"

# create node <Composition>
$comp = $doc.CreateNode('element', 'Composition', '')

# create node <ServiceRef>
$sref = $doc.CreateNode('element', 'ServiceRef', '')
$desc = $doc.CreateTextNode('My service ref')
$sref.AppendChild($desc)

# create node <Source> and append child nodes <Composition> and <ServiceRef>
$src = $doc.CreateNode('element', 'Source', '')
$src.AppendChild($comp)
$src.AppendChild($sref)

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

# save XML file
$doc.Save("C:\service.xml")

Edit: You can loop over several <Service> nodes with something like this (simplified):

$doc.SelectNodes('//Service') | % {
  $comp = $doc.CreateNode('element', 'Composition', '')
  $sref = $doc.CreateNode('element', 'ServiceRef', '')

  $src = $doc.CreateNode('element', 'Source', '')
  $src.AppendChild($comp)
  $src.AppendChild($sref)

  $_.AppendChild($src)
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Thanks - moving closer. So I manually created C:\service.xml and ran the new code and this works. I have several services in an array (i.e $services=@("service1","service2") and was wondering how to loop through them. – Goldstien Feb 26 '13 at 11:33