【问题标题】:Foreach through XML document with Powershell returning multiple nodes通过 XML 文档进行 Foreach,Powershell 返回多个节点
【发布时间】:2017-07-18 22:35:56
【问题描述】:

试图从 XML 文档中收集服务器和环境信息。但是,当我使用 foreach 循环遍历文档时,它会返回树中的两个节点,而不是一次一个。

[xml]$xmlDoc = [xml](Get-Content("C:\temp\compareVHD_info.xml"))

foreach($env in $xmlDoc.pvs.env)
{
    if($env -eq "prod")
    { do stuff}
}

XML:

<pvs>
  <env>
    <prod>
        <primaryServer>
            <name>name</name>
            <storePath>path</storePath>
        </primaryServer>
        <secondaryServer>
            <name>name</name>
            <storePath>path</storePath>
        </secondaryServer>
    </prod>
    <nonProd>
        <primaryServer>
            <name>name</name>
            <storePath>path</storePath>
            <storePath>path</storePath>
            <storePath>path</storePath>
            <storePath>path</storePath>
        </primaryServer>
        <secondaryServer>
            <name>name</name>
            <storePath>path</storePath>
            <storePath>path</storePath>
            <storePath>path</storePath>
            <storePath>path</storePath>
        </secondaryServer>
    </nonProd>
  </env>
</pvs>

我正在尝试收集主要和辅助服务器名称、存储路径和存储路径。但是,当我使用上面的代码时,它会在 $env 变量中返回“prod nonProd”

提前感谢您的帮助!

【问题讨论】:

  • 快速提问。你需要遍历xml文件吗?由于您可以将 xml 文件作为对象加载,因此您可以使用点表示法来访问节点,甚至可以使用 xpath 使用 .SelectSingleNode
  • 我正在尝试使其尽可能动态,以适应不同的客户端设置。所以是的,这是循环遍历它的最佳做法。
  • 当我使用.SelectSingleNode 时,$env 变量有一堆关于对象的信息,而不是来自 XML 的节点字符串。
  • 我想我仍然不确定您为什么不使用 XPath。 $xmlDoc.SelectNodes('/pvs/env/prod') 应该返回所有 prod 节点,如果您可能有多个节点。 XPath 的描述性很强,尽管语法不是很用户友好。如果您想要原始 XML,请引用函数返回的节点的 OuterXmlInnerXml 属性(取决于有意义的内容)。

标签: xml powershell


【解决方案1】:

您发布的代码不可能工作。您的 XML 数据只有一个 &lt;env&gt; 节点,因此您的循环遍历具有 2 个属性(prodnonProd)的单个对象,因此检查 $env -eq "prod" 将始终评估为 $false。您真正想要的是选择&lt;primaryServer&gt; 和/或&lt;secondaryServer&gt; 节点并输出其子节点的值。

[xml]$xml = Get-Content 'C:\path\to\input.xml'

$xml.SelectNodes('//prod/primaryServer') | ForEach-Object {
    New-Object -Type PSObject -Property @{
        Name = $_.name
        Path = $_.storePath -join ';'
    }
} | Export-Csv 'C:\path\to\output.csv' -NoType

如果您希望在同一个文件中的主要和次要节点,请将 XPath expression 更改为 //prod/*[self::primaryServer or self::secondaryServer](如果还有其他同级节点),或者只是 //prod/*(如果这些是 &lt;prod&gt; 的唯一子节点)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多