powershell - Powershel 追加节点
问题描述
我需要在 xml 文档中再添加 3 个节点。我正在尝试以多种方式解决问题,但不幸的是没有结果我的代码正在完成这项工作,但正在添加一个我不想要的属性:如何重复节点?
My code:
function Get-XmlNamespaceManager([ xml ]$XmlDocument, [string]$NamespaceURI = "")
{
# 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.
[System.Xml.XmlNamespaceManager]$xmlNsManager = New-Object System.Xml.XmlNamespaceManager($XmlDocument.NameTable)
$xmlNsManager.AddNamespace("ns", $NamespaceURI)
return ,$xmlNsManager # Need to put the comma before the variable name so that PowerShell doesn't convert it into an Object[].
}
function Get-FullyQualifiedXmlNodePath([string]$NodePath, [string]$NodeSeparatorCharacter = '.')
{
return "/ns:$($NodePath.Replace($($NodeSeparatorCharacter), '/ns:'))"
}
function Get-XmlNode([ xml ]$XmlDocument, [string]$NodePath, [string]$NamespaceURI = "", [string]$NodeSeparatorCharacter = '.')
{
$xmlNsManager = Get-XmlNamespaceManager -XmlDocument $XmlDocument -NamespaceURI $NamespaceURI
[string]$fullyQualifiedNodePath = Get-FullyQualifiedXmlNodePath -NodePath $NodePath -NodeSeparatorCharacter $NodeSeparatorCharacter
# Try and get the node, then return it. Returns $null if the node was not found.
$node = $XmlDocument.SelectSingleNode($fullyQualifiedNodePath, $xmlNsManager)
return $node
}
function Get-XmlNodes([ xml ]$XmlDocument, [string]$NodePath, [string]$NamespaceURI = "", [string]$NodeSeparatorCharacter = '.')
{
$xmlNsManager = Get-XmlNamespaceManager -XmlDocument $XmlDocument -NamespaceURI $NamespaceURI
[string]$fullyQualifiedNodePath = Get-FullyQualifiedXmlNodePath -NodePath $NodePath -NodeSeparatorCharacter $NodeSeparatorCharacter
# Try and get the nodes, then return them. Returns $null if no nodes were found.
$nodes = $XmlDocument.SelectNodes($fullyQualifiedNodePath, $xmlNsManager)
return $nodes
}
$XmlDocument = Get-ChildItem -Path 'C:\Scripts\Add_Languages\Source\' -Recurse -Include "*.imdi" -File | ForEach-Object{
[xml]$Xml = Get-Content $_.FullName
$Keynodes = Get-XmlNodes $Xml -NodePath "METATRANSCRIPT.Session.MDGroup.Content.Keys"
$ref = $Xml.METATRANSCRIPT.Session.MDGroup.Content.Keys.Key | Where {$_.Name -eq 'Topic'}
$Key = $Xml.CreateElement('Key')
$addAtt = $xml.CreateAttribute("Name")
$addAtt.Value = "Topic"
$key.Attributes.Append($addAtt)
$Keynodes.InsertAfter($Key,$ref)
$ref = $Xml.METATRANSCRIPT.Session.MDGroup.Content.Keys.Key | Where {$_.Name -eq 'Keyword'}
$Key = $Xml.CreateElement('Key')
$addAtt = $xml.CreateAttribute("Name")
$addAtt.Value = "Keyword"
$key.Attributes.Append($addAtt)
$Keynodes.InsertAfter($Key,$ref)
$xml.Save($_.FullName)
}
这是我的代码的结果:
<Keys>
<Key Name="Status">Finished</Key>
<Key Name="Keyword">Language profile, interview, multilingualism, younger speaker</Key>
<Key Name="Topic">Language profile</Key>
<Key Name="Topic" xmlns="" /> # <<<<< This node, it's adding the xmlns="" (i don´t need) i need only <Key Name="Topic"/>
<Key Name="Location Address">Kabaroan, Babuyan Claro</Key>
</Keys>
我需要:
<Keys>
<Key Name="Status">Finished</Key>
<Key Name="Keyword">Language profile, interview, multilingualism, younger speaker</Key>
<Key Name="Topic">Language profile</Key>
<Key Name="Topic"></Key>
<Key Name="Topic"></Key>
<Key Name="Topic"></Key>
<Key Name="Location Address">Kabaroan, Babuyan Claro</Key>
</Keys>
再次感谢您在此问题上的任何帮助。
解决方案
首先要说的是$XmlDocument = Get-ChildItem
可以返回多个既DirectoryInfo
和FileInfo
对象。您不应将其视为文件夹中单个项目的完整路径字符串。
xml 的路径以.imdi
. 是文件夹名称还是您将 xml 文件重命名为具有.imdi
扩展名?
接下来,您正在使用Get-XmlNodes
我没有的功能。那是来自某个模块吗?
这是未使用该函数的修改后的代码,假设C:\Scripts\Add_Languages\Source\IVB1-20180808_01.imdi
不是具有奇怪扩展名的单个 xml 文件的完整路径,而是存储 xml 的文件夹的路径。
$path = 'C:\Scripts\Add_Languages\Source\IVB1-20180808_01.imdi'
# get the first XML FileInfo object from this folder
$XmlFile = @(Get-ChildItem -Path $path -Filter '*.xml' -File)[0]
[xml]$Xml = Get-Content $XmlFile.FullName -Raw
# the number of new Topic nodes you want to add
$numberOfTopicsToAdd = 3
$Keynodes = $Xml.METATRANSCRIPT.Session.MDGroup.Content.Keys
# get the first 'Key' childnode with attribute "Name=Topic"
# using XPath:
$refNode = $Keynodes.SelectSingleNode("//Key[@Name='Topic']")
# or using:
# $refNode = @($Keynodes.ChildNodes | Where-Object {$_.LocalName -eq 'Key' -and $_.Name -eq 'Topic'})[0]
# create the new nodes
for ($i = 0; $i -lt $numberOfTopicsToAdd; $i++) {
$Key = $Xml.CreateElement('Key')
$addAtt = $Xml.CreateAttribute("Name")
$addAtt.Value = "Topic"
[void]$key.Attributes.Append($addAtt)
[void]$Keynodes.InsertAfter($Key, $refNode)
}
# create a name for the output xml file by prefixing with 'New_'
$outXml = Join-Path -Path $path -ChildPath ('New_{0}' -f $XmlFile.Name)
$xml.Save($outXml)
输出:
<Keys>
<Key Name="Status">Finished</Key>
<Key Name="Keyword">Language profile, interview, multilingualism, younger speaker</Key>
<Key Name="Topic">Language profile</Key>
<Key Name="Topic" />
<Key Name="Topic" />
<Key Name="Topic" />
<Key Name="Location Address">Kabaroan, Babuyan Claro</Key>
</Keys>
希望有帮助
根据您的评论,我看到的文件夹路径实际上是 xml 文件的完整路径和名称,您所要做的就是将顶行更改为:
# get the content of the XML file
$XmlFile = Get-Item -Path 'C:\Scripts\Add_Languages\Source\IVB1-20180808_01.imdi'
[xml]$Xml = Get-Content $XmlFile.FullName -Raw
其余代码可以保持不变
推荐阅读
- python - 如何在绘图上显示数据框中每列的最高百分比
- reactjs - 带有图标组件的按钮
- asp.net - ORA-12514:TNS 列表器当前不知道连接描述中请求的服务。我能够连接到 sqlplus 和 SQL Developer
- python - 从 2 个列表中删除重复的某些值
- postgresql - PostgreSQL | 剩余的连接槽保留给非复制超级用户连接
- python - Python:计算列表列表中的整体元素
- tfs - 通过克隆 VM 测试 TFS 升级?
- amazon-s3 - 如何将数字海洋空间中的所有文件夹文件权限私有更改为公共?
- c# - 如何在没有麦克风的情况下录制静音
- python - 无法获得带有诅咒的钥匙