2012-06-11 51 views
21

Với PowerShell, tôi muốn thêm một số phần tử phụ vào một cây XML.
Tôi biết ADD ONE phần tử, tôi biết để thêm một hoặc nhiều thuộc tính, nhưng tôi không hiểu cách THÊM các phần tử SEVERAL.thêm các phần tử XML

Một cách có thể là write a sub-XML tree as text
Nhưng tôi không thể sử dụng phương pháp này vì các phần tử không được thêm cùng một lúc.

Để thêm một yếu tố, tôi làm điều đó:

[xml]$xml = get-content $nomfichier 
$newEl = $xml.CreateElement('my_element') 
[void]$xml.root.AppendChild($newEl) 

trình tốt. Điều này cung cấp cho tôi cây XML này:

$xml | fc 
class XmlDocument 
{ 
    root = 
    class XmlElement 
    { 
     datas = 
     class XmlElement 
     { 
      array1 = 
      [ 
       value1 
       value2 
       value3 
      ] 
     } 
     my_element =  <-- the element I just added 
    } 
} 

Bây giờ tôi muốn thêm phần tử con vào 'my_element'. Tôi sử dụng một phương pháp tương tự:

$anotherEl = $xml.CreateElement('my_sub_element') 
[void]$xml.root.my_element.AppendChild($anotherEl) <-- error because $xml.root.my_element is a string 
[void]$newEl.AppendChild($anotherEl)    <-- ok 
$again = $xml.CreateElement('another_one') 
[void]$newEl.AppendChild($again) 

này cung cấp cho cây này XML (partialy hiển thị):

my_element = 
    class XmlElement 
    { 
    my_sub_element = 
    another_one = 
    } 

Đó là những thuộc tính, không phụ yếu tố.
Sub-yếu tố sẽ được hiển thị như thế này:

my_element = 
    [ 
    my_sub_element 
    another_one 
    ] 

Câu hỏi: Làm thế nào để thêm một số phần tử con, cùng một lúc?

Trả lời

35

Có một cái nhìn vào ví dụ sau:

# Document creation 
[xml]$xmlDoc = New-Object system.Xml.XmlDocument 
$xmlDoc.LoadXml("<?xml version=`"1.0`" encoding=`"utf-8`"?><Racine></Racine>") 

# Creation of a node and its text 
$xmlElt = $xmlDoc.CreateElement("Machine") 
$xmlText = $xmlDoc.CreateTextNode("Mach1") 
$xmlElt.AppendChild($xmlText) 

# Creation of a sub node 
$xmlSubElt = $xmlDoc.CreateElement("Adapters") 
$xmlSubText = $xmlDoc.CreateTextNode("Network") 
$xmlSubElt.AppendChild($xmlSubText) 
$xmlElt.AppendChild($xmlSubElt) 

# Creation of an attribute in the principal node 
$xmlAtt = $xmlDoc.CreateAttribute("IP") 
$xmlAtt.Value = "128.200.1.1" 
$xmlElt.Attributes.Append($xmlAtt) 

# Add the node to the document 
$xmlDoc.LastChild.AppendChild($xmlElt); 

# Store to a file 
$xmlDoc.Save("c:\Temp\Temp\Fic.xml") 

Edited

Ghi chú: Using a relative path in Save will not do what you expect.

+1

Giải pháp tốt hơn nhiều so với những gì tôi tìm thấy cho đến bây giờ! Và sạch hơn. Cảm ơn. –

+0

Điều này hoạt động tốt đẹp. Vấn đề của tôi là, nó viết nhiều thứ lên bàn điều khiển. Gỡ lỗi cho thấy điều đó xảy ra ở dòng này: $ xmlSubElt.AppendChild ($ xmlSubText) nếu tôi viết "> $ null" vào cuối. Một cái gì đó khác được viết ra Tôi có thể chặn nó không? – Tomi

+0

Thay thế '> $ null' bằng' | out-null'. – JPBlanc

21

Tôi thích tạo xml bằng tay, thay vì sử dụng API để xây dựng nút bằng nút, như imho bằng tay, nó sẽ dễ đọc hơn và dễ bảo trì hơn.

Dưới đây là một ví dụ:

$pathToConfig = $env:windir + "\Microsoft.NET\Framework64\v4.0.30319\Config\web.config" 

$xml = [xml] (type $pathToConfig) 

[xml]$appSettingsXml = @" 
<appSettings> 
    <add key="WebMachineIdentifier" value="$webIdentifier" /> 
</appSettings> 
"@ 


$xml.configuration.AppendChild($xml.ImportNode($appSettingsXml.appSettings, $true)) 
$xml.Save($pathToConfig) 
+0

Cảm ơn, đây chính xác là những gì tôi đang tìm kiếm! –

+0

Điều này làm việc rất tốt cho tôi. Và, tôi thích có thể xây dựng và đọc xml theo cách tự nhiên hơn như bạn đã chỉ ra. – rrirower

+0

Được viết dưới dạng hàm (và có thể xử lý không gian tên tốt hơn?) Tại https://gist.github.com/thoemmi/2937183 –

1

Kiểm tra này mã mẫu. Nó có mọi thứ bạn cần để tạo XML từ cratch:

function addElement($e1, $name2, $value2, $attr2) 
{ 
    if ($e1.gettype().name -eq "XmlDocument") {$e2 = $e1.CreateElement($name2)} 
    else {$e2 = $e1.ownerDocument.CreateElement($name2)} 
    if ($attr2) {$e2.setAttribute($value2,$attr2)} 
    elseif ($value2) {$e2.InnerText = "$value2"} 
    return $e1.AppendChild($e2) 
} 

function formatXML([xml]$xml) 
{ 
    $sb = New-Object System.Text.StringBuilder 
    $sw = New-Object System.IO.StringWriter($sb) 
    $wr = New-Object System.Xml.XmlTextWriter($sw) 
    $wr.Formatting = [System.Xml.Formatting]::Indented 
    $xml.Save($wr) 
    return $sb.ToString() 
} 

$xml = New-Object system.Xml.XmlDocument 
$xml1 = addElement $xml "a" 
$xml2 = addElement $xml1 "b" 
$xml3 = addElement $xml2 "c" "value" 
$xml3 = addElement $xml2 "d" "attrib" "attrib_value" 

write-host `nFormatted XML:`r`n`n(formatXML $xml.OuterXml) 
Các vấn đề liên quan