Search code examples
xmlpowershellpowershell-5.0

PowerShell: how to concatenate InnerText values into a single string?


I am looping through multiple XML files in a directory. Each file has identical structure:

<input>
    <filePattern>
        <marketCode>cbf_d</marketCode>
        <format>txt</format>
    </filePattern>
</input>
<input>
    <filePattern>
        <marketCode>lvd_cbf_b</marketCode>
        <format>csv</format>
    </filePattern>
</input>
<input>
    <filePattern>
        <marketCode>cbf_a</marketCode>
        <format>zip</format>
    </filePattern>
</input>

My purpose is to loop through each input node within a file, extract InnerText values from marketCode and format and then concatenate them into a single string:

Get-ChildItem -Path 'C:\test\cbf\*merge*' -Recurse |
ForEach-Object {
    $xml_file = $_ 
    
    $content = [xml](Get-Content $xml_file)
    $nodes = $content.SelectNodes('//input')    

    
    foreach ($node in $nodes) {
        $marketCode = $node.SelectNodes('//input/filePattern/marketCode').InnerText
        $format = $node.SelectNodes('//input/filePattern/format').InnerText
        
                                    
    }
    #Trying to cancatenate InnerText values here:
    $marketCode + '_' + $format
    
        
}

The output that I get:

cbf_d
lvd_cbf_b
cbf_a
_
txt
csv
zip

The output that I expect:

cbf_d_txt
lvd_cbf_b_csv
cbf_a_zip

How to properly concatenate values of InnerText?


Solution

  • By using //input you are resetting your base path to "global" - which means ignoring your context node $node. The solution is to use a relative path (relative to $node) in your SelectNodes expressions. Furthermore, you only concatenated the strings once per file - and not once per <input> element - so the concatenation operation needs to be shifted into the loop.

    Get-ChildItem -Path 'C:\test\cbf\*merge*' -Recurse |
    ForEach-Object {
        $xml_file = $_ 
        
        $content = [xml](Get-Content $xml_file)
        $nodes = $content.SelectNodes('//input')    
    
        
        foreach ($node in $nodes) {
            $marketCode = $node.SelectNodes('filePattern/marketCode').InnerText
            $format = $node.SelectNodes('filePattern/format').InnerText
            #Trying to concatenate InnerText values here:
            $marketCode + '_' + $format
        }
    }
    

    The output is as desired.