在特定节点下插入值

时间:2016-09-05 08:16:29

标签: xml powershell

我正在尝试使用powershell为所有现有用户Firefox配置文件操作Firefox mimeTypes.rdf。

我想添加以下条目

<RDF:li RDF:resource="urn:mimetype:application/x-zip-compressed"/>

具体在:

<RDF:Seq RDF:about="urn:mimetypes:root">

根据http://kb.mozillazine.org/MimeTypes.rdf的指南。我已经计算出从引用XML文档追加InnerXml来更新RDF:Description节点,但是RDF:Seq直接输入使我无法进入。

<?xml version="1.0"?>
<RDF:RDF xmlns:NC="http://home.netscape.com/NC-rdf#"         xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <RDF:Seq RDF:about="urn:schemes:root">
    <RDF:li RDF:resource="urn:scheme:webcal"/>
    <RDF:li RDF:resource="urn:scheme:ircs"/>
    <RDF:li RDF:resource="urn:scheme:mailto"/>
    <RDF:li RDF:resource="urn:scheme:irc"/>
  </RDF:Seq>
  <RDF:Seq RDF:about="urn:mimetypes:root">
    <RDF:li RDF:resource="urn:mimetype:application/x-ica"/>
  </RDF:Seq>
 </RDF:RDF>

已经尝试了许多方法:

[xml]$s = (Select-Xml -Path .\seq.rdf -XPath / ).node
$xpathquery  = "/RDF:RDF[@xmlns:NC=`"http://home.netscape.com/NC-rdf#`"]/RDF:Seq[@RDF:about=`"urn:mimetypes:root`"]/RDF:li"
$nsmgr = $s.NameTable
$nsmgr.AddNamespace('NC',"http://home.netscape.com/NC-rdf#")
$nsmgr.AddNamespace('RDF',"http://www.w3.org/1999/02/22-rdf-syntax-ns#" )

Select-Xml -Xml $s -XPath $xpathquery -Namespace $nsmgr 

然后使用AppendChild() / CreateElement()方法

$child = $s.CreateElement
AppendChild($child)

然后以各种方式使用AppendChild()

$null = $s.RDF.seq.Where{
            ($_.About -match 'urn:mimetype:application')
        }.Component.AppendChild($child)
来自参考文件的

ImportNode()

foreach ($Node in $a.RDF.Seq.ChildNodes) {
    ($xc.DocumentElement.AppendChild($s.ImportNode($a.RDF.Seq.ChildNodes, $true)))
    #$xc.DocumentElement.Description.SetAttribute("description", "Config file for testing")
}

正如你所看到的,我没有扎实地掌握操作XML而感到困惑。部分问题是XPath查询(如果需要)。

2 个答案:

答案 0 :(得分:1)

我尝试重新创建你的任务并将其作为解决方案:

[xml]$a=Get-Content "C:\temp\XML.xml"
#clone first about node
$b=($a.rdf.seq|where {$_.about -eq "urn:mimetypes:root"}).li.clone()
#modify the cloned node
$b.resource="urn:mimetype:application/x-zip-compressed"
#add modified node to xml
($a.rdf.seq|where {$_.about -eq "urn:mimetypes:root"}).AppendChild($b)

#save in new file
$a.Save("C:\temp\XML-Updated.xml")

结果是

<?xml version="1.0"?>
<RDF:RDF xmlns:NC="http://home.netscape.com/NC-rdf#" xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <RDF:Seq RDF:about="urn:schemes:root">
    <RDF:li RDF:resource="urn:scheme:webcal" />
    <RDF:li RDF:resource="urn:scheme:ircs" />
    <RDF:li RDF:resource="urn:scheme:mailto" />
    <RDF:li RDF:resource="urn:scheme:irc" />
  </RDF:Seq>
  <RDF:Seq RDF:about="urn:mimetypes:root">
    <RDF:li RDF:resource="urn:mimetype:application/x-ica" />
    <RDF:li RDF:resource="urn:mimetype:application/x-zip-compressed" />
  </RDF:Seq>
</RDF:RDF>

我现在没时间挖掘,但希望这可以帮到你

答案 1 :(得分:1)

为变量分配名称表并不会神奇地创建名称空间管理器。您需要实例化命名空间管理器并使用名称表初始化它:

[xml]$xml = Get-Content 'C:\path\to\your.xml'
$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)

否则AddNamespace()调用会抛出错误。

然后您创建并附加新元素,例如从内到外:

  1. 创建RDF:resource属性并将值指定给属性。
  2. 创建一个RDF:li节点,并将该属性附加到节点的属性。
  3. 选择要添加新节点的节点并将其附加。
  4. $NC_NS  = 'http://home.netscape.com/NC-rdf#'
    $RDF_NS = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    
    [xml]$xml = Get-Content 'C:\path\to\input.xml'
    $nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
    $nsm.AddNamespace('NC', $NC_NS)
    $nsm.AddNamespace('RDF', $RDF_NS)
    
    $attr = $xml.CreateAttribute('RDF', 'resource', $RDF_NS)
    $attr.Value = 'urn:mimetype:application/x-zip-compressed'
    
    $node = $xml.CreateElement('RDF', 'li', $RDF_NS)
    $node.Attributes.Append($attr) | Out-Null
    
    $parent = $xml.SelectSingleNode("//RDF:Seq[@RDF:about='urn:mimetypes:root']", $nsm)
    $parent.AppendChild($node) | Out-Null
    
    xml.Save('C:\path\to\output.xml')