PowerShell:如何将 InnerText 值连接成一个字符串?

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

我正在遍历目录中的多个 XML 文件。每个文件都具有相同的结构:

<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>

我的目的是遍历文件中的每个 input 节点,从 marketCodeformat 中提取 InnerText 值,然后将它们连接成一个字符串:

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
    
        
}

我得到的输出:

cbf_d
lvd_cbf_b
cbf_a
_
txt
csv
zip

我期望的输出:

cbf_d_txt
lvd_cbf_b_csv
cbf_a_zip

如何正确连接 InnerText 的值?

通过使用 //input,您将基本路径重置为“全局”——这意味着忽略上下文节点 $node。解决方案是在 SelectNodes 表达式中使用相对路径(相对于 $node)。此外,每个文件只连接一次字符串 - 而不是每个 <input> 元素一次 - 因此连接操作需要转移到循环中。

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
    }
}

输出如愿。

补充 , which explains the problems with your attempt well and offers an effective solution, with a more concise solution that uses the Select-Xml cmdlet:

Get-ChildItem C:\test\cbf\*merge* -Recurse |
  Select-Xml '//input/filePattern' | 
    ForEach-Object { $_.Node.marketCode, $_.Node.format -join '_' }
  • Select-Xml 可以直接对输入文件执行 XPath 查询,而不必将文件内容解析成 XML DOM ([xml] ( System.Xml.XmlDocument)) 手动。

  • 它输出 SelectXmlInfo 带有元数据的包装器对象,其 .Node 属性 包含匹配的节点。

    • 顺便说一句:鉴于通常不需要元数据,如果可以将 Select-Xml 指示为仅 return 节点会很方便,这是 [=24= 的主题].
  • 感谢 PowerShell 的便利 ,您可以访问节点上的子元素 returned 简单地作为 properties(例如, .marketCode 来访问 <marketCode> 子元素),如果这些元素只有文本内容(只有一个子文本节点),则直接 return 编辑文本(不需要 .InnerText).