2017-02-23 47 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