Выберите элемент XML по значению атрибута и добавьте элемент

У меня есть этот xml файл с этой структурой:

<?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>

Я хочу добавить строку в компанию → category → category1 "Office2" → category2 "Project2" Линия:

<category3 name="Test4"/>

Ive пробовал это:

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

Я знаю, как это сделать с одним подэлементом, и как клонировать и добавлять. Но я не знаю, с чего начать.

Ответ 1

Не знаю, есть ли более короткий путь, но это должно работать:

$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")

Основные моменты здесь - использование where для получения элементов с заданными значениями атрибутов и создания нового элемента и нового атрибута.

Другим возможным решением для получения элемента "target" является использование XPath:

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

Ответ 2

[XML]$XML=gc "C:\file.xml"

это короткий способ загрузить xml

Ответ 3

Старайтесь не бросать XML - он примерно в 7 раз медленнее, чем загружает его:

$xml = New-Object -TypeName XML
$xml.Load([path to XML])