AppendChild к XML в определенной позиции - PullRequest
1 голос
/ 08 ноября 2019

У меня есть XML-файл, который выглядит следующим образом:

<ViewsFile>
 <Categories>
  <ViewCategory Name="General">
   <Views>
    <View Name="firstView">
     ...
    </View>
    <View Name="secondView">
     ...
    </View>
   </Views>
  </ViewCategory>
  <ViewCategory Name="Bookings">
   <Views>
    <View Name="firstView">
     ...
    </View>
    <View Name="secondView">
     ...
    </View>
   </Views>
  </ViewCategory>
<ViewCategory Name="Activities">
   <Views>
    <View Name="firstView">
     ...
    </View>
   </Views>
  </ViewCategory>
 </Categories>
</ViewsFile>

Теперь я хочу добавить следующий XML-файл к первому, учитывая правильную позицию, а именно родительский элемент сname 'Bookings':

<ViewCategory Name="Bookings">
 <Views>
  <View Name="newView">
   ...
  </View>
 </Views>
</ViewCategory>

Таким образом, окончательный XML-файл должен выглядеть следующим образом:

<ViewsFile>
 <Categories>
  <ViewCategory Name="General">
   <Views>
    <View Name="firstView">
     ...
    </View>
    <View Name="secondView">
     ...
    </View>
   </Views>
  </ViewCategory>
  <ViewCategory Name="Bookings">
   <Views>
    <View Name="firstView">
     ...
    </View>
    <View Name="secondView">
     ...
    </View>
    <View Name="newView">
    ...
    </View>
   </Views>
  </ViewCategory>
<ViewCategory Name="Activities">
   <Views>
    <View Name="firstView">
     ...
    </View>
   </Views>
  </ViewCategory>
 </Categories>
</ViewsFile>

Мой сценарий PowerShell на данный момент выглядит следующим образом:

[xml] $x = Get-Content C:\Users\user\Desktop\exitingViews.xml;
[xml] $y = Get-Content C:\Users\user\Desktop\newView.xml;

$x.ViewsFile.Categories.ViewCategory.Views.AppendChild($x.ImportNode(($y.ViewCategory.Views.View), $true));
$x.Save('C:\Users\user\Desktop\final.xml'); 

Но он только добавляет новый вид к последней категории.

Существует ли какая-либо "простая" возможность определить, куда добавить дочерний узел?

1 Ответ

2 голосов
/ 08 ноября 2019

Когда вы используете удобную адаптацию PowerShell для XML DOM , предоставляемую System.Xml.XmlDocument, оператор . выполняет перечисление членов , что означает, что доступнапример, .ViewCategories вернет все дочерние элементы с этим именем.

Поэтому вам необходимо отфильтровать массив .ViewCategories , чтобы получить конкретный интересующий элемент,что вы можете сделать с помощью массива .Where() (PSv4 +):

$x.ViewsFile.Categories.ViewCategory.Where({ $_.Name -eq 'Bookings' }).Views.AppendChild($x.ImportNode(($y.ViewCategory.Views.View), $true))

В качестве альтернативы, использовать запрос XPath чтобы найти интересующий элемент, с помощью .SelectSingleNode():

$x.SelectSingleNode('//ViewCategory[@Name = "Bookings"]').Views.AppendChild($x.ImportNode(($y.ViewCategory.Views.View), $true))

Примечание: я воспользовался ярлыком с //, который находит элементы ViewCategoyв любом месте документа, но вы можете обозначить весь путь как /ViewsFile/Categories/ViewCategory[@Name = "Bookings"], что быстрее и позволяет избежать двусмысленности.

...