2015-03-25 2 views
3

PowerShell У меня есть XML-документ, отформатированный как это:доступ #text имущества XmlAttribute в

<root> 
<obj> 
    <indexlist> 
     <index name="NUMD" value="val1" /> 
     <index name="DATE" value="val2" /> 
    </indexlist> 
</obj> 
</root> 

Теперь я хотел бы изменить атрибут значение индекса элемента, в котором имя задано значение «DATE». Я получаю атрибут, как это:

$attr = $xml.selectnodes("//obj/indexlist/index[@name='DATE']/@value") 

можно просмотреть значение, введя следующее:

$attr.'#text' 

, но я не могу изменить его:

$attr.'#text' = 'foo' 
The property '#text' cannot be found on this object. Verify that the property exists and can be set. 
At line:1 char:1 
+ $n.'#text' = 'foo' 
+ ~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : PropertyAssignmentException 

Как изменить значение XMLAttribute?


Я хотел бы также придерживаться XPath возвращения атрибут непосредственно, если это возможно, так как конечный пользователь этого сценария будет определять элементы и атрибуты для изменения в файле конфигурации с помощью XPath.
При использовании XPath для атрибутов пользователь может просто предоставить атрибут для изменения, а будущее значение - всего двумя аргументами: XPath и значением.

ответ

3

Кроме #text, вы можете также доступа XmlAttribute «S значение с помощью Value собственности:

$attr = $xml.SelectSingleNode("//obj/indexlist/index[@name='DATE']/@value") 

#print old value 
$attr.Value 

#update attribute value 
$attr.Value = "new value" 

#print new value 
$attr.Value 

Обратите внимание, что Value в $attr.Value является собственностью компании XmlAttribute. На него не влияет тот факт, что атрибут в вашем XML называется value.

+2

На самом деле проблема заключалась в том, что я использовал 'selectnodes' вместо' selectsinglenode', как вы. когда я просто echo'd моя '$ attr' powershell покажет мне значение' # text' каждый раз и также скажет, что возвращаемый тип является XmlAttribute, если я сделал '$ attr | gm'. но на самом деле возвращаемым типом кажется arrair или collection, который, конечно же, не имеет свойства 'value'. используя мой подход с '$ attr [0] .value' вместо' $ attr.value' также работает, но это был ваш ответ и использование 'selectsinglenode', который привел меня в правильном направлении;) спасибо :) – wullxz

1

Не выбирайте атрибут, выберите узел. Атрибуты узла будут представлены как свойства и могут быть изменены как таковой:

$node = $xml.SelectSingleNode("//obj/indexlist/index[@name='DATE']") 
$node.value = 'foo' 

Используйте цикл, если вам необходимо изменить несколько узлов:

$nodes = $xml.SelectNodes("//obj/indexlist/index[@name='DATE']") 
foreach ($node in $nodes) { 
    $node.value = 'foo' 
} 
0

Конечно, вы также можете рассматривать XMl как текстовый файл и удалять объявления пространства имен с помощью SED или таких.

+0

Добро пожаловать ТАК. Это спорный вопрос, если это ответ или комментарий; см. также http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags для того, как некоторые люди в SO думают о разборе XML с регулярным выражением: | – Foon

+0

Да, скорее комментарий, чем ответ, потому что он даже не предлагает решение, а просто идею. Спасибо за ваш вклад. – wullxz

Смежные вопросы