Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

powershell - Select XML element by attribute value and add an element

I have this XML-file with this structure:

<?xml version="1.0" encoding="utf-8"?>
<company>
<category>
    <category1 name="Office1">
        <category2 name="Project1">
            <category3 name="Test1"/>
            <category3 name="Test2"/>
        </category2>
        <category2 name="Project2">
            <category3 name="Test1"/>
            <category3 name="Test2"/>
            <category3 name="Test3"/>
        </category2>
     </category1>

     <category1 name="Office2">
        <category2 name="Project1">
            <category3 name="Test1"/>
            <category3 name="Test2"/>
        </category2>
        <category2 name="Project2">
            <category3 name="Test1"/>
            <category3 name="Test2"/>
            <category3 name="Test3"/>
        </category2>
      </category1>
</category>  
</company>

I want to add a line to company -> category -> category1 "Office2" -> category2 "Project2" The line is:

<category3 name="Test4"/>

I've tried this:

$Path = "C:file.xml"
$xml = [xml](get-content $Path)
$xml.Load($Path)
$test = $xml.company.category
$test.category1 *what to do here*

I know how to do this with one sub-element, and how to clone and add. But I don't know where to start with this one.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Don't know if there is a shorter way, but this should work:

$Path = "C:file.xml"
$xml = [xml](get-content $Path)
$xml.Load($Path)
$target = (($xml.company.category.category1|where {$_.name -eq "Office2"}).category2|where {$_.name -eq "Project2"})
$addElem = $xml.CreateElement("Category3")
$addAtt = $xml.CreateAttribute("name")
$addAtt.Value = "Test4"
$addElem.Attributes.Append($addAtt)
$target.AppendChild($addElem)
$xml.Save("C:file1.xml")

The main points here are the usage of where to get the elements with the given attribute values and the creation of a new element and a new attribute.

Another possible solution to get the "target" element is the usage of XPath:

$target = $xml.SelectSingleNode('//company/category/category1[@name="Office2"]/category2[@name="Project2"]')

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...