【问题标题】:How to write values to XML file with Powershell如何使用 Powershell 将值写入 XML 文件
【发布时间】:2021-01-25 21:52:07
【问题描述】:

我是 Powershell 新手,需要将一些数据写入现有的 XML 文件。我发现了很多简单的 XML 示例,这些示例无法用于我需要写入的文件。我想做的是写信给:

Bld_version.build
Bld_version.major
Bld_version.minor
Bld_version.patch

在这个文件中:

<?xml version='1.0' encoding='UTF-8'?>
<Project Type="Project" LVVersion="20008000">
    <Property Name="NI.LV.All.SourceOnly" Type="Bool">true</Property>
    <Property Name="NI.Project.Description" Type="Str"></Property>
    <Item Name="My Computer" Type="My Computer">
        <Property Name="server.app.propertiesEnabled" Type="Bool">true</Property>
        <Property Name="server.control.propertiesEnabled" Type="Bool">true</Property>
        <Item Name="private" Type="Folder">
            <Item Name="Type Defs" Type="Folder">
                <Item Name="App Data.ctl" Type="VI" URL="../App Data.ctl"/>
                <Item Name="App States.ctl" Type="VI" URL="../App States.ctl"/>
                <Item Name="Check Options States.ctl" Type="VI" URL="../Check Options States.ctl"/>
                <Item Name="LV versions.ctl" Type="VI" URL="../LV versions.ctl"/>
            </Item>
            <Item Name="Build Help Text.vi" Type="VI" URL="../Build Help Text.vi"/>
            <Item Name="Check Folder Permission.vi" Type="VI" URL="../Check Folder Permission.vi"/>
            <Item Name="Check Options.vi" Type="VI" URL="../Check Options.vi"/>
            <Item Name="Convert Files.vi" Type="VI" URL="../Convert Files.vi"/>
            <Item Name="Get Vipb Path.vi" Type="VI" URL="../Get Vipb Path.vi"/>
            <Item Name="Prepare Temp Directory.vi" Type="VI" URL="../Prepare Temp Directory.vi"/>
            <Item Name="Save for Previous Version (lib).vi" Type="VI" URL="../Save for Previous Version (lib).vi"/>
            <Item Name="Save for Previous Version (proj).vi" Type="VI" URL="../Save for Previous Version (proj).vi"/>
            <Item Name="Save for Previous Version (vi).vi" Type="VI" URL="../Save for Previous Version (vi).vi"/>
        </Item>
        <Item Name="public" Type="Folder">
            <Item Name="Vip Tool.vi" Type="VI" URL="../Vip Tool.vi"/>
        </Item>
        <Item Name="res" Type="Folder">
            <Item Name="vip.ico" Type="Document" URL="../vip.ico"/>
        </Item>
        <Item Name="Build Specifications" Type="Build">
            <Item Name="vip-tool" Type="EXE">
                <Property Name="Bld_version.build" Type="Int">20</Property>
                <Property Name="Bld_version.major" Type="Int">1</Property>
                <Property Name="Bld_version.minor" Type="Int">1</Property>
                <Property Name="Bld_version.patch" Type="Int">1</Property>
            </Item>
        </Item>
    </Item>
</Project>

我什至无法读取这四个值,因为我无法找到“导航”到数据的方法。创建对象和加载文件非常简单,但在 vip-tool 节点下读取/写入数据是另一回事。

PS U:\> $var = New-Object System.XML.XMLDocument
PS U:\> $var = Get-Content -Path "C:\Vip Build Tool.lvproj" -ErrorAction "Stop"
PS U:\> $var.Project."Item"."Item"

Name                 Type
----                 ----
private              Folder
public               Folder
res                  Folder
Build Specifications Build

也许有人可以帮我解决这个问题,显然我仍然不了解如何获取数据或写入数据。

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    您可以使用XPath query 直接选择节点,而不是将您的 xml 文档导航到要更改的确切节点:

    $xml.SelectNodes('//Property[@Name="Bld_version.major"]')
    

    这将返回文档中所有 &lt;Property&gt; 节点的 XPathNodeList,这些节点具有属性 @Name 和分配给此属性的值“Bld_version.major”。

    在您的情况下,这足以准确识别文档中的一个 XmlElement,因此您可以选择选择结果的第一个元素并覆盖它的 #text 字段:

    $xml.SelectNodes('//Property[@Name="Bld_version.major"]')[0]."#text" = 2
    

    这是一个将构建版本设置为 2.1.2 的示例:

    $filePath = "C:\Vip Build Tool.lvproj"
    $xml = (Get-Content -Path $filePath) -as [xml]
    $xml.SelectNodes('//Property[@Name="Bld_version.major"]')[0]."#text" = 2
    $xml.SelectNodes('//Property[@Name="Bld_version.minor"]')[0]."#text" = 1
    $xml.SelectNodes('//Property[@Name="Bld_version.patch"]')[0]."#text" = 2
    $xml.save($filePath)
    

    【讨论】:

    • 谢谢你的例子,就像一个魅力。我唯一要改变的是删除第 2 行中的 -as 并将 XML 转换移动到“=”之后。感谢您的帮助!
    【解决方案2】:

    另一种方法是使用点对象表示法,与 XPath 相比,它的优点是它不区分大小写:

    $path = "C:\Vip Build Tool.lvproj"
    $xml = New-Object System.XML.XMLDocument
    $xml.Load($path)
    
    $buildSpecs = ($xml.Project.Item.Item | Where-Object { $_.Name -eq "Build Specifications" }).Item.Property
    ($buildSpecs | Where-Object { $_.Name -eq "Bld_version.build" }).InnerText = 123
    ($buildSpecs | Where-Object { $_.Name -eq "Bld_version.major" }).InnerText = 2
    ($buildSpecs | Where-Object { $_.Name -eq "Bld_version.minor" }).InnerText = 3
    ($buildSpecs | Where-Object { $_.Name -eq "Bld_version.patch" }).InnerText = 4
    
    $xml.Save($path)
    

    【讨论】:

    • 感谢您的示例也按预期工作。就像您的解决方案不区分大小写一样。
    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 2010-12-27
    • 2014-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多