简体   繁体   English

如何使用 Powershell 将值写入 XML 文件

[英]How to write values to XML file with Powershell

I'm new to Powershell and need to write some data to an existing XML file.我是 Powershell 的新手,需要将一些数据写入现有的 XML 文件。 I found a lot of simple XML examples which I can't adopt to the file I need to write to.我发现了很多简单的 XML 示例,我无法将它们应用于我需要写入的文件中。 What I'm trying to do is to write to:我想做的是写信给:

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

in this File:在这个文件中:

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

I can't even read the four values cause I can't figure out a way to "navigate" to the data.我什至无法读取这四个值,因为我无法找到“导航”到数据的方法。 Creating the object and loading the file is pretty straight forward but reading/ writing the data under the vip-tool node is a different beast.创建 object 并加载文件非常简单,但在 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

Maybe someone can help me with this, there is obviously something basic I still don't understand about how to get to the data or write to it.也许有人可以帮助我,显然我仍然不了解如何获取数据或写入数据的一些基本内容。

Instead of navigating your xml document to the exact node, that you want to change, you can use a XPath query to select the node directly:无需将 xml 文档导航到要更改的确切节点,您可以直接使用XPath 查询到 select 节点:

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

This will return a XPathNodeList of all <Property> nodes in the document, that have an attribute @Name and the value "Bld_version.major" assigned to this attribute.这将返回文档中所有<Property>节点的 XPathNodeList,这些节点具有属性@Name和分配给该属性的值“Bld_version.major”。

In your case that is enough to identify exactly one XmlElement in your document, so you can select the first element of your selection result and overwrite it's #text field:在您的情况下,这足以准确识别文档中的一个 XmlElement,因此您可以 select 选择结果的第一个元素并覆盖它的#text字段:

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

Here is an example that sets your build version to 2.1.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)

Another way is to use the dotted object notation, where you have the advantage that it works case-insensitive as opposed to XPath:另一种方法是使用带点的 object 表示法,与 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM