我正在一个目录中遍历多个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节点,从marketCode和format提取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的值
发布于 2020-10-14 20:13:27
通过使用//input,您将基本路径重置为“全局”--这意味着忽略上下文节点$node。解决方案是在$node表达式中使用相对路径(相对于SelectNodes )。此外,您只在每个文件(而不是每个<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
}
}输出结果如所需。
发布于 2020-10-15 02:37:59
为了补充zx485 485的有用答案,它很好地解释了您的尝试中存在的问题,并提供了一个有效的解决方案,并提供了一个使用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 ([xml] (System.Xml.XmlDocument))。SelectXmlInfo包装器对象,其.Node属性包含匹配的节点。- As an aside: Given that the metadata is often not needed, it would be convenient if `Select-Xml` could be instructed to return the nodes only, which is the subject of [GitHub feature request #13669](https://github.com/PowerShell/PowerShell/issues/13669).<marketCode>子元素的.marketCode ),如果这些元素只有文本内容(只有子文本节点),则直接返回文本(不需要.InnerText)。https://stackoverflow.com/questions/64360690
复制相似问题