0

I'm going to parse a nested xml file using PowerShell. Is there a way to traverse its childnodes and the nodes of its child one by one?

For example:

<?xml version="1.0"?>
<root xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
  <Node1 name="A"/>
  <Node2 name="B"/>
  <Node3>
    <Element1 id="1" type="Element">
      <State value = "live" /State>
      <Child1 name="dogName">
        <SubChild1 id="11111">
        </SubChild1>
      </Child1>
      <Child2>
        <SubChild2 name="color" value="red" />
        <SubChild2 name="skin" value="none" />
        <SubChild2 name="other" value="lost" />
      </Child2>
      <Child3>
        <SubChild3>FlagMark=GO</SubChild3>
        <SubChild3>Dog</SubChild3>
      </Child3>
    </Element1>
    <Element2 id="2" type="Element">
      <State value = "live">
      <Child1 name="catName">
        <SubChild1 id="22222">
        </SubChild1>
      </Child1>
      <Child2>
        <SubChild2 name="color" value="brown" />
        <SubChild2 name="skin" value="thick" />
        <SubChild2 name="other" value="unknown" />
      </Child2>
      <Child3>
        <SubChild3>FlagMark=Run</SubChild3>
        <SubChild3>Cat</SubChild3>
      </Child3>
    </Element2>
    <Element3>
      ...
    </Element3>
  </Node3>
</root>

How can I get each child node of by its name and value? How can I get child nodes of one by one and print?

4

1 Answer 1

0

Here's how you can parse XML inside PowerShell; one special trick is the use of the [xml] type accelerator

  1. Create a variable to hold the XML string:

    # Declare our XML string
    $xmlContent = @"
    <?xml version="1.0"?>
    <root xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
      <Node1 name="A"/>
      <Node2 name="B"/>
      <Node3>
        <Element1 id="1" type="Element">
          <State value = "live"/>
          <Child1 name="dogName">
            <SubChild1 id="11111"/>
          </Child1>
          <Child2>
            <SubChild2 name="color" value="red"/>
            <SubChild2 name="skin" value="none"/>
            <SubChild2 name="other" value="lost"/>
          </Child2>
          <Child3>
            <SubChild3>FlagMark=GO</SubChild3>
            <SubChild3>Dog</SubChild3>
          </Child3>
        </Element1>
        <!-- ...snip... -->
      </Node3>
    </root>
    "@
    
  2. Use the [xml] type accelerator to parse the string into XML:

    # Convert the string to XML with the [xml] type accelerator
    $xml = [xml]$xmlContent
    
  3. Use .selectNodes to get a child, e.g. Child2:

    # Get all Child2 nodes
    $child2Nodes = $xml.SelectNodes("//Child2")
    
  4. Iterate over each <Child2> node, and each of its <SubChild> nodes

    # Get a child
    foreach ($child2 in $child2Nodes) {
       # Iterate over each subchild
       foreach ($subChild2 in $child2.ChildNodes) {
          # Print their names and values
          Write-Host "SubChild2 Name: $($subChild2.getAttribute('name')), Value: $($subChild2.getAttribute('value'))"
       }
    }
    

You can then use the same idea to enumerate Child3:

# Get all Child3 nodes
$child3Nodes = $xml.SelectNodes("//Child3")

foreach ($child3 in $child3Nodes) {
    # Iterate over each child of Child3 and print
    foreach ($subChild3 in $child3.ChildNodes) {
        # Print SubChild3 content
        Write-Host "SubChild3 Content: $($subChild3.'#text')"
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.