简体   繁体   English

更新子节点及其属性信息 - Powershell

[英]Updating Child Nodes and their attributes information - Powershell

I am trying to update macaddress information in one of the XML files available on my servers.我正在尝试更新服务器上可用的 XML 文件之一中的 macaddress 信息。 I see two types of situations where the我看到两种情况

<configuration>
  <serverIdentification id="1d230d28-08bc-4a12-a56a-7dacf7f09282" />
  <NetworkBinding ReSync="false" PublicAddress="dev-000450-02a.gsccloud.ninja" PublicPort="">
   <macAddresses />
  </NetworkBinding>
.
.
.
</configuration>

or或者

 <configuration>
      <serverIdentification id="1d230d28-08bc-4a12-a56a-7dacf7f09282" />
      <NetworkBinding ReSync="false" PublicAddress="dev-000450-02a.gsccloud.ninja" PublicPort="">
         <macaddresses>

       </macaddresses>
      </NetworkBinding>
    .
    .
    .
    </configuration>

The desired XMLData should be the like the one shown below.所需的 XMLData 应如下所示。 Please note address(Addr) value is empty.请注意地址(地址)值为空。 This will get updated through some other mechanism.这将通过其他一些机制得到更新。 So don't worry about it.所以不用担心。 For now I just want the XML data to look like shown below.现在我只希望 XML 数据如下所示。

<configuration>
          <serverIdentification id="1d230d28-08bc-4a12-a56a-7dacf7f09282" />
          <NetworkBinding ReSync="false" PublicAddress="dev-000450-02a.gsccloud.ninja" PublicPort="">
             <macaddresses>
              <Mac Addr="" />
           </macaddresses>
          </NetworkBinding>
        .
        .
        .
        </configuration>

From what I can see is that the child node "macAddresses" is present but the innerxml data is empty.从我可以看到的是存在子节点“macAddresses”但innerxml数据为空。

 $xmlfilepath  = "C\somepath\path"
    [xml] $XMLData = Get-Content -LiteralPath $xmlfilepath -ErrorAction Stop

在此处输入图片说明

Sorry my knowledge of XML manipulation is not that great.抱歉,我对 XML 操作的了解不是很好。 Any info would be greatly appreciated.任何信息,将不胜感激。

# Read the input file into an XML DOM.
[xml] $xmlData = Get-Content -Raw -LiteralPath $xmlfilepath -ErrorAction Stop

# Target the <macAddresses> element and add the desired child element
# via its .InnerXml property.
# Note the required use of indexing syntax (['macAddresses']).
$xmlData.configuration.NetworkBinding['macAddresses'].InnerXml = '<Mac Addr="" />'

# $xmlData is now updated; inspect with .OuterXml or save to a file
# with, say, $xmlData.Save("$PWD/new.xml")

Note: Index notation - $xmlData.configuration.NetworkBinding['macAddresses'] - rather than dot notation - $xmlData.configuration.NetworkBinding.macAddresses must be used in order to reliably target the <macAddresses> element:注意:索引符号 - $xmlData.configuration.NetworkBinding['macAddresses'] - 而不是点符号- 必须使用$xmlData.configuration.NetworkBinding.macAddresses以可靠地定位<macAddresses>元素:

PowerShell's dot notation ( .macAddresses ) is usually very convenient, but in the case of leaf elements (those that either have no content at all or text content only, except if they have attributes ), it returns the element's string content rather than the element object itself ( XmlElement ) : PowerShell 的点符号( .macAddresses ) 通常非常方便,但对于元素(那些根本没有内容或只有文本内容,除非它们有attributes ),它返回元素的字符串内容而不是元素对象本身XmlElement

  • You can use dot notation to modify the text content of a leaf element (eg, $xmlData.configuration.NetworkBinding.macAddresses = 'foo' )可以使用点符号来修改叶元素的文本内容(例如, $xmlData.configuration.NetworkBinding.macAddresses = 'foo'

  • You cannot use dot notation to access properties or call methods on leaf elements (eg, $xmlData.configuration.NetworkBinding.macAddresses.InnerXml = '<foo/>' fails - .macAddresses is treated as a [string] , and a string has no .InnerXml property)不能使用点表示法访问属性调用叶元素上的方法(例如, $xmlData.configuration.NetworkBinding.macAddresses.InnerXml = '<foo/>'失败- .macAddresses被视为[string] ,并且字符串具有没有.InnerXml属性)

    • Note that non -leaf elements are always returned as themselves ( XmlElement instances).请注意,叶元素始终作为自身返回( XmlElement实例)。

By contrast, index notation ( ['macAddresses'] ), a type-native feature, allows you target child elements by name as well, but consistently returns them as XmlElement objects , so you can access properties such as .InnerXml on them or call methods such as .SetAttribute() .相比之下,索引符号( ['macAddresses'] ) 是一种类型本机功能,它也允许您按名称定位子元素,但始终将它们作为XmlElement对象返回,因此您可以访问它们上的.InnerXml等属性或调用.SetAttribute()等方法。

Note, however, that this index notation by design only ever returns the first element of that name among the children, even if multiple ones are present (which PowerShell's dot notation exposes as an array );但是请注意,这种索引表示法在设计上只会返回子代中该名称的第一个元素,即使存在多个元素(PowerShell 的点表示法将其公开为数组); to target an element other than the first one , use目标比第一个使用以外的元素
.SelectNodes(<name>)[<n>] on the element , where <n> is a positional index, as in an array. .SelectNodes(<name>)[<n>]在 element 上,其中<n>是位置索引,就像在数组中一样。

In your case, since you want to add a child node to the <macAddresses> element, via assignment to the .InnerXml property, index notation is therefore required.在您的情况下,由于您想通过分配给.InnerXml属性将节点添加到<macAddresses>元素,因此需要索引符号。

I was able to achieve this with a different solution.我能够使用不同的解决方案来实现这一点。 This is a snippet of my code which I will be using within a function.这是我将在函数中使用的代码片段。

[xml] $XMLData = Get-Content -LiteralPath $xmlfilepath -ErrorAction Stop

$appSettingsXml = @"
<macAddresses>
    <Mac Addr="" />
</macAddresses> 
"@ 


    if(($XMLData.configuration.NetworkBinding.InnerXml -eq "<macAddresses></macAddresses>") -or ($XMLData.configuration.NetworkBinding.InnerXml -eq "<macAddresses />")){
        $XMLData.configuration.NetworkBinding.InnerXml=""
        $XMLData.configuration.NetworkBinding.InnerXml=$appSettingsXml
    }
.
.
.
.
$XMLData.save($xmlfilepath)

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

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