【问题标题】:Load XML containing custom namespace加载包含自定义命名空间的 XML
【发布时间】:2016-10-14 11:13:54
【问题描述】:

使用 PowerShell 脚本动态附加 XML 标记。 在这种情况下,尝试为 NLog 添加自定义 ElasticSearch 目标(来自here)。

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

当使用将$source 转换为 XML 时

[xml]$source

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

我收到以下错误

无法将值“”转换为类型“System.Xml.XmlDocument”。错误:“'xsi' 是一个未声明的前缀。”

有什么建议吗?

差不多,但还不完全:

我可以使用ConvertTo-Xml $source -as Document,但结果没有使用&lt;target&gt;标签,它使用&lt;Object&gt;,在这种情况下不起作用。

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

【问题讨论】:

    标签: xml powershell


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2012-10-25
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2013-11-20
      相关资源
      最近更新 更多