web-dev-qa-db-fra.com

Sélectionner un élément XML par valeur d'attribut et ajouter un élément

J'ai ce fichier XML avec cette 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>

Je souhaite ajouter une ligne à société -> catégorie -> catégorie1 "Bureau2" -> catégorie2 "Projet2" La ligne est la suivante: 

<category3 name="Test4"/>

J'ai essayé ceci:

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

Je sais comment faire cela avec un sous-élément, et comment cloner et ajouter. Mais je ne sais pas par où commencer avec celui-ci. 

12
alexfyren

Je ne sais pas s'il existe un moyen plus court, mais cela devrait fonctionner:

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

Les points principaux ici sont l'utilisation de where pour obtenir les éléments avec les valeurs d'attribut données et la création d'un nouvel élément et d'un nouvel attribut.

Une autre solution possible pour obtenir l'élément "cible" est l'utilisation de XPath:

$target = $xml.SelectSingleNode('//company/category/category1[@name="Office2"]/category2[@name="Project2"]')
22
Ocaso Protal
[XML]$XML=gc "C:\file.xml"

est un moyen rapide de charger le XML

0
User