建立自定义 XML 文件
Posted
技术标签:
【中文标题】建立自定义 XML 文件【英文标题】:Build up custom XML-File 【发布时间】:2017-02-23 15:32:06 【问题描述】:我需要一些帮助来使用 Powershell 构建 XML 文件。我以前从未这样做过。
一开始我觉得很幸运并尝试了“Export-Clixml”,但它并没有产生我想要的输出。我需要干净的 XML。
我有一个现有的 XML 文件,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
</DeploymentScript>
我从 XML 中读出设置并在 Powershell 中做一些事情。我创建了一个对象,如下所示:
TaskSequenceNumber TaskSequenceName
------------------ ----------------
0 01_Base
1 02_XA
我想将此对象保存在我的 XML 文件中。 (附加) XML 文件最终应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
<Deploy>
<SequenceData>
<TaskSequenceNumber>1</TaskSequenceNumber>
<TaskSequenceName>01_Base</TaskSequenceName>
</SequenceData>
<SequenceData>
<TaskSequenceNumber>2</TaskSequenceNumber>
<TaskSequenceName>02_XA</TaskSequenceName>
</SequenceData>
</Deploy>
</DeploymentScript>
我尝试了一些 .NET XML 方法,但没有得到结果。 有人能给我举个例子吗?
.
编辑: 感谢“Frode F.”!这里是最新的代码:
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
</DeploymentScript>
"@
#$xml = [xml]( Get-Content -Path "$env:USERPROFILE\Desktop\Deploy-Settings.xml" )
$TaskSequences = [pscustomobject]@TaskSequenceNumber=0;TaskSequenceName="01_Base",[pscustomobject]@TaskSequenceNumber=1;TaskSequenceName="02_XA"
#Add Deploy-node
$DeployNode = $xml.CreateElement( "Deploy" )
$xml.DeploymentScript.AppendChild( $DeployNode ) > $null
foreach ( $element in $TaskSequences )
$SeqDataNode = ([xml]@"
<SequenceData>
<TaskSequenceNumber>$($element.TaskSequenceNumber + 1)</TaskSequenceNumber>
<TaskSequenceName>$($element.TaskSequenceName)</TaskSequenceName>
</SequenceData>
"@).FirstChild
#Add to Deploy-node
$DeployNode.AppendChild( $xml.ImportNode( $SeqDataNode,$true ) ) > $null
$xml.Save( "$env:USERPROFILE\Desktop\Test.xml" )
【问题讨论】:
您确定架构吗?多个根节点会产生错误。你需要把设置和部署放在里面 很抱歉,我没有太多使用 XML 的经验。使用 XML-Notepad 创建了示例。我已经更新了提到的 XML。希望现在可以了。 下一次,包含您尝试过但不起作用的代码,以便我们帮助您修复您的代码 【参考方案1】:您可以通过在 .NET 中使用 xml-classes 来尝试这样的事情:
#SampleInput
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<Settings>
...
</Settings>
"@
$TaskSequences = [pscustomobject]@TaskSequenceNumber=0;TaskSequenceName="01_Base",[pscustomobject]@TaskSequenceNumber=1;TaskSequenceName="02_XA"
#$xml = [xml](Get-Content -Path InputFile.xml)
#$TaskSequences = Get-RealDataFromSomeWhere
#Create new xml and remove root node
$newxml = $xml.Clone()
$newxml.RemoveChild($newxml.SelectSingleNode("/Settings")) > $null
#Add new DeploymentScript root-node with copy of Settings
$DeploymentScriptNode = $newxml.CreateElement("DeploymentScript")
$DeploymentScriptNode.AppendChild($newxml.ImportNode($xml.SelectSingleNode("/Settings"),$true)) > $null
$newxml.AppendChild($DeploymentScriptNode) > $null
#Add Deploy-node
$DeployNode = $newxml.CreateElement("Deploy")
$DeploymentScriptNode.AppendChild($DeployNode) > $null
foreach ($ts in $TaskSequences)
#Create SequenceData-element per TS
$SeqDataNode = $newxml.CreateElement("SequenceData")
$SeqDataNode.AppendChild($newxml.CreateElement("TaskSequenceNumber")) > $null
$SeqDataNode.AppendChild($newxml.CreateElement("TaskSequenceName")) > $null
$SeqDataNode.TaskSequenceNumber = "$($ts.TaskSequenceNumber + 1)"
$SeqDataNode.TaskSequenceName = $ts.TaskSequenceName
#Add to Deploy-node
$DeployNode.AppendChild($SeqDataNode) > $null
$newxml.Save("$env:USERPROFILE\Desktop\Test.xml")
或者凌乱但更短的字符串方法:
#SampleInput
$xml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<Settings>
...
</Settings>
"@
$TaskSequences = [pscustomobject]@TaskSequenceNumber=0;TaskSequenceName="01_Base",[pscustomobject]@TaskSequenceNumber=1;TaskSequenceName="02_XA"
#$xml = [xml](Get-Content -Path InputFile.xml)
#$TaskSequences = Get-RealDataFromSomeWhere
#Create new xml and remove root node
$newxml = [xml]@"
$($xml.FirstChild | ? $_.NodeType -eq 'XmlDeclaration' | % $_.OuterXml )
<DeploymentScript>
$($xml.SelectSingleNode("/Settings").OuterXml)
<Deploy>
$($TaskSequences | %
"<SequenceData>
<TaskSequenceNumber>$($_.TaskSequenceNumber + 1)</TaskSequenceNumber>
<TaskSequenceName>$($_.TaskSequenceName)</TaskSequenceName>
</SequenceData>" )
</Deploy>
</DeploymentScript>
"@
$newxml.Save("$env:USERPROFILE\Desktop\Test.xml")
Test.xml:
<?xml version="1.0" encoding="utf-8"?>
<DeploymentScript>
<Settings>
...
</Settings>
<Deploy>
<SequenceData>
<TaskSequenceNumber>1</TaskSequenceNumber>
<TaskSequenceName>01_Base</TaskSequenceName>
</SequenceData>
<SequenceData>
<TaskSequenceNumber>2</TaskSequenceNumber>
<TaskSequenceName>02_XA</TaskSequenceName>
</SequenceData>
</Deploy>
</DeploymentScript>
【讨论】:
非常感谢您的努力。根据您的代码,我得到了第一个结果。我已经用最新的代码编辑了我的请求。对于 "$SeqDataNode = ([xml]@" ..." 部分 -> 我仍然想知道,为什么你在那里编写纯 XML 代码?难道没有像“appendchild”这样的方法吗?你做到了吗?节省时间还是最好的方法? 我觉得所有的方法都很丑。对于这个简单的节点,我喜欢 xml 代码,但它可以很容易地重写为使用方法。和其他节点一样。 刚刚在我的主脚本中用扩展数据实现了这个。我认为这很好用。谢谢以上是关于建立自定义 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章