2017-02-23 73 views
0

我需要一些帮助,以使用Powershell构建XML文件。我从来没有这样做过。构建自定义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") 
+1

您确定该模式吗?多个根节点会产生错误。你需要把设置和部署在里面 –

+0

对不起,我没有太多的XML经验。用XML记事本创建了这个例子。我已经更新了提到的XML。希望现在好了。 – Walhalla

+0

下一次,包括您尝试过的代码无效,因此我们可以帮助您修复代码 –

回答

2

你可以通过在.NET中使用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.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> 
+0

非常感谢您的努力。根据你的代码,我得到了第一个结果。我用最新的代码编辑了我的请求。对于部分“$ SeqDataNode =([xml] @”...“ - >我仍然想知道,为什么你在那里写简单的XML代码?有没有像”appendchild“这样的方法?为了节省时间还是最好的方法? – Walhalla

+0

我认为所有的方法都很难看。对于这个简单的节点,我喜欢xml-code,但是它可以很容易地被重写为使用方法,就像其他节点一样。 –

+0

刚才实现了这个我的主要脚本是扩展数据,我认为这很有用 – Walhalla