[英]XML update with powershell
我有以下示例XML:
<?xml version="1.0" encoding="utf-8"?>
<SQLUsers>
<SQLFile>
<FileVersion>260</FileVersion>
<FileDate>06.14.2014</FileDate>
</SQLFile>
<SQLAccount>
<user001>
<AccountName>user001</AccountName>
<SQLSysAdmin>Adm_user001</SQLSysAdmin>
<SQLSysAdminPassword>P@ssw0rd</SQLSysAdminPassword>
<SQLReadOnlyUser>user004</SQLReadOnlyUser>
<SQLReadOnlyUserPassword>P@ssw0rd</SQLReadOnlyUserPassword>
<CreationDate>06.13.2014</CreationDate>
<InstanceID>InstanceID</InstanceID>
</user001>
</SQLAccount>
<SQLAccount>
<user002>
<AccountName>user002</AccountName>
<SQLSysAdmin>Adm_user001</SQLSysAdmin>
<SQLSysAdminPassword>P@ssw0rd</SQLSysAdminPassword>
<SQLReadOnlyUser>user005</SQLReadOnlyUser>
<SQLReadOnlyUserPassword>P@ssw0rd</SQLReadOnlyUserPassword>
<CreationDate>06.13.2014</CreationDate>
<InstanceID>InstanceID</InstanceID>
</user002>
</SQLAccount>
</SQLUsers>
我應該更新此XML文件,以便在“ UserXXX”節點下添加一個新元素。 像這樣的東西:
<user002>
<AccountName>user002</AccountName>
<SQLSysAdmin>Adm_user001</SQLSysAdmin>
<SQLSysAdminPassword>P@ssw0rd</SQLSysAdminPassword>
<SQLReadOnlyUser>user005</SQLReadOnlyUser>
<SQLReadOnlyUserPassword>P@ssw0rd</SQLReadOnlyUserPassword>
<CreationDate>06.13.2014</CreationDate>
<InstanceID>InstanceID</InstanceID>
<DatabaseName>database1</DatabaseName>
<DatabaseName>database2</DatabaseName>
</user002>
我有以下powershell腳本,該腳本接受用戶名和數據庫名稱作為參數:
param($accountName,$database)
$ErrorActionPreference = "Stop"
[string]$date = Get-Date -format "MM.dd.yyyy"
$Instanceid = "Testid"
[xml] $xml = gc "C:\LogFiles\$Instanceid-SQLUsers.xml"
$child = $xml.CreateElement("DatabaseName")
$child.SetAttribute('DatabaseName','$database')
$xml.SQLUsers.SQLAccount.$accountName.AppendChild($child)
$xml.save("C:\LogFiles\$Instanceid-SQLUsers_update.xml")
但是,我收到以下錯誤:
You cannot call a method on a null-valued expression.
At D:\Scripts\AttachUserToDB_XML3.ps1:12 char:1
+ $xml.SQLUsers.SQLAccount.$accountName.AppendChild($child)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvokeMethodOnNull
我也用innerXML嘗試過,但是沒有用。 任何幫助,將不勝感激!
非常感謝!
由於您的xml結構具有多個sqlaccount標記,因此您將無法導航到確切的用戶帳戶元素。
可以將xml結構更改為具有單個sqlaccounts並列出所有用戶,或者使用xpath查詢來檢索確切的用戶元素並在其上調用appendChild。
您的xml設計錯誤。 節點應具有“標准”名稱,以便您可以根據模式驗證xml。 您有一個user0002
-node,這有點用,因為在AccountName
user0002
中已經指定了該值。 這個:
<SQLAccount>
<user002>
<AccountName>user002</AccountName>
</use002>
</SQLAccount>
應該簡化為以下內容(因為AccountName元素已經包含用戶名/唯一值):
<SQLAccount>
<AccountName>user002</AccountName>
</SQLAccount>
但是要回答您的問題,我想指出一些事情:
問題是,當您運行$xml.SQLUsers.SQLAccount.$accountName
,將得到兩個項目的數組:空對象和xmlelement,因此需要指定$xml.SQLUsers.SQLAccount.$accountName[1]
得到你的節點。 如果該帳戶不存在,您仍然會得到一個包含兩個項目的數組:兩個空對象。 因此,請記住驗證是否已找到該節點。 例如 檢查以查看AccountName
-property是否存在。
您還創建錯誤的元素。 您的示例不包括databasename
-attribute,但是您的腳本嘗試創建一個。
您的腳本從一個文件讀取,然后保存到另一個文件。 為了能夠像示例中所示添加多個數據庫,腳本需要在一個調用中支持多個數據庫名稱。
您可以嘗試以下方法:
function UpdateXML {
param($accountName,[string[]]$database)
$Instanceid = "Testid"
[xml] $xml = gc "C:\LogFiles\$Instanceid-SQLUsers.xml"
#case sensitive! easy to read
#$accountnode = $xml.SelectSingleNode("//AccountName[. = '$accountName']").parentnode
#case insensitive
$accountnode = $xml.SQLUsers.SQLAccount.$accountName[1]
#If a node for the account was found
if($accountnode.AccountName) {
foreach ($dbname in $database) {
$element = $xml.CreateElement("DatabaseName")
$element.InnerText = $dbname
$accountnode.AppendChild($element) | Out-Null
}
$xml.save("C:\LogFiles\$Instanceid-SQLUsers_update.xml")
} else {
Write-Error "Account '$accountName' doesn't exist!"
}
}
UpdateXML -accountName "user002" -database "database1", "database2"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.