0

I need to add a new element to existing nodes in an XML. The current structure essentially looks like this:

<CommandManagerResults>
   <ListReports>
    <Row>
      <Name>aaa</Name>
    </Row>
    <Row>
      <Name>bbb</Name>
    </Row>
   </ListReports>
   <ListDocuments>
    <Row>
      <Name>ccc</Name>
    </Row>
    <Row>
      <Name>ddd</Name>
    </Row>
   </ListDocuments>
</CommandManagerResults>

I need to add an element in all the "Row" nodes. The code I have so far:

$directory = "E:\temp"
cd $directory

[xml]$XmlDocument = Get-Content ".\test.xml"

$ProjectName = $XmlDocument.CreateElement("ProjectName")
$ProjectName.InnerText = "test"

$temp = $XmlDocument.SelectNodes("//Row")

foreach ($row in $temp){
    $row.AppendChild($ProjectName)
    $XmlDocument.Save($directory + '\test.xml')
}

However, only the very last "Row" node is getting saved with the new "ProjectName" element. I added '$row | FL' inside the foreach loop and it shows each Row as having the ProjectName element as being there through each iteration of the loop, unfortunately no matter if I save inside or after the foreach loop only the last Row node is saving with the ProjectName element. How it's coming out:

<CommandManagerResults>
   <ListReports>
    <Row>
      <Name>aaa</Name>
    </Row>
    <Row>
      <Name>bbb</Name>
    </Row>
   </ListReports>
   <ListDocuments>
    <Row>
      <Name>ccc</Name>
    </Row>
    <Row>
      <Name>ddd</Name>
      <ProjectName>Test</ProjectName>
    </Row>
   </ListDocuments>
</CommandManagerResults>

What I want the structure to look like in the end:

<CommandManagerResults>
   <ListReports>
    <Row>
      <Name>aaa</Name>
      <ProjectName>Test</ProjectName>
    </Row>
    <Row>
      <Name>bbb</Name>
      <ProjectName>Test</ProjectName>
    </Row>
   </ListReports>
   <ListDocuments>
    <Row>
      <Name>ccc</Name>
      <ProjectName>Test</ProjectName>
    </Row>
    <Row>
      <Name>ddd</Name>
      <ProjectName>Test</ProjectName>
    </Row>
   </ListDocuments>
</CommandManagerResults>

FYI, very new to Powershell and XMLs so hopefully everything I've said makes sense and I'm at least heading down the right path.

1
  • for this purpose it is better to use XSLT Commented Feb 11, 2021 at 5:40

1 Answer 1

1

You have to create a new element for each element to be added. Finally, the Save() call should be only at the end, when you are done with the document.

$temp = $XmlDocument.SelectNodes("//Row")

foreach ($row in $temp){

    $ProjectName = $XmlDocument.CreateElement("ProjectName")
    $ProjectName.InnerText = "test"

    $row.AppendChild($ProjectName)
}

$XmlDocument.Save($directory + '\test.xml')

On a side note [xml]$XmlDocument = Get-Content ".\test.xml", while being convenient, is bad practice. It works just by chance, as most XML documents these days are UTF-8 encoded, which happens to be the default encoding used by Get-Content. But Get-Content knows nothing about the actual value of the XML "encoding" attribute.

Proper way to load the XML document, while respecting its "encoding" attribute:

$xml = [xml]::new()
$xml.Load((Convert-Path ".\test.xml")) 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much! I've been struggling with this far too long, glad it was something simple. Thank you again!!!
@p0ck3tace Cheers!
just updated the loading of the XML as well, thanks for the pointer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.