2016-10-14 55 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 
相关问题