[英]Updating XML element and attribute value using Powershell
這是我正在使用的 XML。 這是在 sqlproj 文件中,想要將 ArtifactReference 的 Include 屬性中的值“..\cwdb.dacpac”和節點元素 HintPath 更新為新值。
<ItemGroup>
<ArtifactReference Include="$(DacPacRootPath)\Extensions\Microsoft\SQLDB\Extensions\SqlServer\AzureV12\SqlSchemas\master.dacpac">
<HintPath>$(DacPacRootPath)\Extensions\Microsoft\SQLDB\Extensions\SqlServer\AzureV12\SqlSchemas\master.dacpac</HintPath>
<SuppressMissingDependenciesErrors>True</SuppressMissingDependenciesErrors>
<DatabaseVariableLiteralValue>master</DatabaseVariableLiteralValue>
</ArtifactReference>
<ArtifactReference Include="..\cwdb.dacpac">
<HintPath>..\cwdb.dacpac</HintPath>
<SuppressMissingDependenciesErrors>True</SuppressMissingDependenciesErrors>
<DatabaseVariableLiteralValue>cwdb</DatabaseVariableLiteralValue>
</ArtifactReference>
</ItemGroup>
以下部分代碼基於此博客https://blogs.like10.com/2014/06/17/versioning-your-sql-server-database-using-team-build-and-release-management/ ,但是它不會更新值。 在調用 function Set-XMlElementsTextValue 時,傳遞元素路徑 HintPath 以更新其值。 我還如何更改 Include 屬性值?
function Get-XmlNode([ xml ]$XmlDocument, [string]$NodePath, [string]$NamespaceURI = “”, [string]$NodeSeparatorCharacter = ‘.’)
{
# If a Namespace URI was not given, use the Xml document’s default namespace.
if ([string]::IsNullOrEmpty($NamespaceURI))
{
$NamespaceURI = $XmlDocument.DocumentElement.NamespaceURI
}
# In order for SelectSingleNode() to actually work, we need to use the fully qualified node path along with an Xml Namespace Manager, so set them up.
$xmlNsManager = New-Object System.Xml.XmlNamespaceManager($XmlDocument.NameTable)
$xmlNsManager.AddNamespace(“ns”, $NamespaceURI)
$fullyQualifiedNodePath = “/ns:$($NodePath.Replace($($NodeSeparatorCharacter), ‘/ns:’))”
$node = $XmlDocument.SelectSingleNode($fullyQualifiedNodePath, $xmlNsManager)
return $node
}
function Set-XMlElementsTextValue([ xml ]$XmlDocument, [string]$ElementPath, [string]$TextValue)
{
$node = Get-XmlNode -XmlDocument $XmlDocument -NodePath $ElementPath
# If the node exists, update its value.
if ($node)
{
$node.InnerText = $TextValue
}
}
$path = "C:\Shared\DACPAC\"
$NewText = $path + "cwdb.dacpac"
$files = gci $env:BUILD_SOURCESDIRECTORY -recurse |
?{ $_.Extension -eq ".sqlproj" } |
foreach { gci -Path $_.FullName -Recurse -include *.sqlproj }
if($files)
{
foreach ($file in $files) {
[xml]$fileContent = Get-Content($file)
attrib $file -r
#Read in the file contents, update the element's value, and save the file.
Set-XMlElementsTextValue -XmlDocument $fileContent -ElementPath "Project.ItemGroup.ArtifactReference.HintPath" -TextValue $NewText
$fileContent.Save($file)
}
}
else
{
Write-Output "Found no *.sqlproj files."
}
我更新了我的代碼並刪除了函數並將命名空間包含在主代碼中。 這可能不是最優雅的解決方案,但這里是修改后的有效代碼:
if($files)
{
foreach ($file in $files) {
[xml]$fileContent = Get-Content($file)
attrib $file -r
$XPath = "/ns:Project/ns:ItemGroup/ns:ArtifactReference[@Include='..\cwdb.dacpac']"
$namespace = $fileContent.DocumentElement.NamespaceURI
$ns = New-Object System.Xml.XmlNamespaceManager($fileContent.NameTable)
$ns.AddNamespace("ns", $namespace)
$artifacts = $fileContent.SelectSingleNode($XPath, $ns)
# update HintPath node value
$artifacts.SelectSingleNode("./ns:HintPath", $ns)."#text" = $NewText
Foreach ($artifact in $artifacts)
{ # update Include attribute value
$artifact.SetAttribute("Include", $NewText)
}
$fileContent.Save($file)
Write-Output "$file.FullName = update applied"
}
}
else
{
Write-Output "Found no *.sqlproj files."
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.