2016-10-14 51 views
0

使用PowerShell腳本動態添加XML標記。 在這種情況下,試圖爲NLog添加自定義ElasticSearch目標(從here)。加載包含自定義名稱空間的XML

$source = '<target name="elastic" xsi:type="BufferingWrapper"> </target>' 

當使用

[xml]$source 

$xml = New-Object -TypeName System.Xml.XmlDocument 
$xml.LoadXml($source) 

我收到以下錯誤

Cannot convert value "<targetname="elastic" xsi:type="BufferingWrapper"> </target>" to type "System.Xml.XmlDocument". Error: "'xsi' is an undeclared prefix."

任何建議轉換$source到XML?

差不多了,但也不能令人信服:

我可以使用ConvertTo-Xml $source -as Document但結果不使用<target>標籤,它使用<Object>,這並不在這種情況下工作。

<?xml version="1.0" encoding="utf-8"?> 
<Objects> 
    <Object Type="System.String">&lt;target name="elastic" xsi:type="BufferingWrapper" 
<Objects> 

回答

1

this answer描述你可以加載XML片段:

$source = '<target name="elastic" xsi:type="BufferingWrapper"></target>' 
$sreader = New-Object IO.StringReader $source 
$xreader = New-Object Xml.XmlTextReader $sreader 
$xreader.Namespaces = $false 
$fragment = New-Object Xml.XmlDocument 
$fragment.Load($xreader) 

但是,假設你想導入片段到另一個XML數據結構在某些時候,這樣做可能會導致其他問題(例如參見this question)。

要解決此問題,使用適當的命名空間定義一個虛擬的根節點添加到您的XML片段:

$source = '<target name="elastic" xsi:type="BufferingWrapper"> </target>' 
[xml]$fragment = "<dummy xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>$source</dummy>" 

這樣,你可以導入節點到另一個這樣的XML文檔(提供的其他XML文件還包含適當的命名空間定義):

[xml]$xml = Get-Content 'C:\path\to\master.xml' 

$nsm = New-Object Xml.XmlNamespaceManager $xml.NameTable 
$nsm.AddNamespace('xsi', $xml.NamespaceURI) 

$node = $xml.ImportNode($fragment.DocumentElement.target, $true) 

$targets = $xml.SelectSingleNode('//targets', $nsm) 
$targets.AppendChild($node) | Out-Null 
相關問題