【问题标题】:Parse xml in powershell在 powershell 中解析 xml
【发布时间】:2010-12-15 19:04:00
【问题描述】:

我有以下 xml:

<?xml version="1.0" encoding="UTF-8"?>
<sections>
  <section name="Options">
    <item key="HLVersionControlWebServiceURL" value="http://www.personec.no/webservices/HLVersionControl/HLVersionControl.asmx" />
    <item key="AltinnWebServiceURL" value="https://www.altinn.no/webservices/DataExchange.asmx" />
    <item key="WorkDir" value="F:\Altinn\Work\" />
    <item key="CatalogDir" value="F:\Altinn\Work\" />
  </section>
  <section name="Users">
    <item key="1" value="Admin" name="Administrator" fNr="" password="" entsystype="1" entsysid="180967" entsyspassword="" lastLogin="20091111161516" allowra0500="1" allowrf1037="1" allowra01821="1" allowra01822="0" allowrf1015="1" altinnuserpassword="/qwHHYwYinE=" />
  </section>
  <section name="SchemaTypes">
    <item key="RF1037" displayname="Terminoppgave" inputdir="F:\Altinn\Work\" validationschema=".\melding-669-8570.xsd" isSubForm="0" isSignable="0" />
    <item key="RA0500" displayname="SSB Lønnsstatistikk" inputdir="C:\Program Files (x86)\Personec\Altinn Monitor\Work\" validationschema=".\melding-868-7612.xsd" isSubForm="0" isSignable="0" />
    <item key="RA01821" displayname="SSB Fraværsstatistikk bedrift" inputdir="C:\Program Files (x86)\Personec\Altinn Monitor\Work\" validationschema=".\melding-862-6190.xsd" isSubForm="0" isSignable="0" />
    <item key="RF1015" displayname="Årsoppgave m/ LTO" inputdir="C:\Program Files (x86)\Personec\Altinn Monitor\Work\" validationschema=".\melding-210-7928.xsd" orid="210" orversion="7928" isSubForm="0" isSignable="1" />
    <item key="RF1015U" displayname="" inputdir="" validationschema=".\melding-1083-7930.xsd" orid="1083" orversion="7930" isSubForm="1" isSignable="1" />
  </section>
</sections>

我需要在 Powershell 中更改项目键 WorkDir。当使用“常规” xml-read 时,我会进入顶部部分(选项、用户等),但不是每个部分中的“项目键”节点。如何在 powershell 中编辑 WorkDir 的值? (我意识到我可以只使用脏字符串替换,但我宁愿“正确”地做到这一点。

【问题讨论】:

标签: xml powershell


【解决方案1】:

这个版本使用了更多的 PowerShell,并使用 WorkDir 键处理多个项目的情况:

$xml = [xml](Get-Content foo.xml)
$xpath = "/sections/section/item[@key='WorkDir']" 
Microsoft.PowerShell.Utility\Select-Xml $xml -XPath $xpath |
    Foreach {$_.Node.SetAttribute('value', $pwd)}
$xml.Save("$pwd\bar.xml")

注意,如果您安装了 PowerShell Community Extensions,您可以使用 Format-Xml cmdlet 格式化输出并通过 Out-File 保存它,例如:

$xml | Format-Xml -AttributesOnNewLine | Out-File bar.xml -enc utf8

OTOH $xml.Save() 更简单,但您必须记住,如果您只指定文件名,它可能没有正确的当前目录。这就是我在第一个示例中使用“$pwd\bar.xml”的原因。这不是像 Out-File 这样的 PowerShell cmdlet 的问题。

【讨论】:

    【解决方案2】:

    你可以试试这个

    $xmlFile = "d:\sample.xml"
    
    [xml]$doc = Get-Content $xmlFile
    $node = $doc.SelectSingleNode("/sections/section/item[@key='WorkDir']")
    $node.Value = "New-Value"
    $doc.Save($xmlFile)
    

    您仍将使用一些 .Net 类和 XPath 查询来选择节点。

    【讨论】:

    • 您可以使用 PowerShell 2.0 中的 Select-Xml cmdlet 代替 SelectSingleNode 方法调用。
    • Select-Xml 在 PowerShell 1.0 中可用,但我认为以上方法仍然是访问和修改属性值的最简单方法。
    • 仅供参考,Select-Xml 在 PowerShell 1.0 中可用。它确实带有 PowerShell 社区扩展,这可能就是您在 1.0 中看到它的原因。
    • 是的。我们遇到了编写部署脚本的问题——我认为如果我们需要 Format-Xml,则需要在部署框上安装社区扩展,然后才能运行部署。但是,使用 Save 时,使用 $pwd 超级有用可以获取反映 Get-Content 的行为。
    【解决方案3】:

    您可以像这样从 PowerShell 将 XML 加载到 LINQ XDocument 类中:

    [Reflection.Assembly]::LoadWithpartialName("System.Xml.Linq") | Out-Null
    $xDoc = [System.Xml.Linq.XDocument]::Parse($myXmlString)
    

    从那里您可以使用通常的 LINQ to XML 方法来替换 this example 中的属性。如果您愿意,可以以类似的方式使用较旧的 XmlDocument 类。

    【讨论】:

    • 请记住,PowerShell 不支持您可以在实例上调用 ext 方法的 C# 3.0 静态扩展方法语法。而 IIRC,PowerShell 也不支持调用泛型方法。因此,只要您只是创建 XLINQ 对象就可以,但如果您尝试使用 LINQ 查询功能 (System.Linq.Enumerable),那将是徒劳的。
    【解决方案4】:
    $invocation = (Get-Variable MyInvocation).Value
    $directorypath = Split-Path $invocation.MyCommand.Path
    
    
    [xml]$userfile = Get-Content $directorypath\MainSetting.xml
    $Value = $userfile.GetElementsByTagName("node")
    
    Foreach ($ValueName in $Value)
    {
        $FinalValue=$ValueName.InnerXML
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-18
      • 1970-01-01
      • 2013-08-04
      • 2020-12-30
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 2020-05-19
      相关资源
      最近更新 更多