Цикл Foreach для изменения значений XML (-1) и сохранения в тот же файл - PullRequest
0 голосов
/ 21 марта 2019

Я пытаюсь изменить значение в XML-файле, где у меня есть цена:

<Document-InventoryReport>
  <InventoryReport-Lines>
    <Line>
      <Line-Item>
        <id>1</id>
        <UnitNetPrice>13.9200</UnitNetPrice>
      </Line-Item>
      <Line-Item>
        <id>2</id>
        <UnitNetPrice>13.9200</UnitNetPrice>
      </Line-Item>
    </Line>
  </InventoryReport-Lines>
</Document-InventoryReport>

Я хочу заменить значение <UnitNetPrice> значением минус 1,0.

Я сделал некоторый скрипт, но он не сохраняет это значение, используя foreach:

$xml = Get-Content -Path C:\Test\file.xml
foreach ($element in $xml.'Document-InventoryReport'.'InventoryReport-Lines'.'Line'.'Line-Item'.'UnitNetPrice') {
    $element - 1.0
} 

У кого-нибудь есть идеи?

1 Ответ

3 голосов
/ 21 марта 2019

Есть несколько проблем с вашим кодом:

  1. Вы не анализируете данные XML, поэтому вы не сможете получить доступ к значениям.

    Используйте либо

    [xml]$xml = Get-Content 'C:\Test\file.xml'
    

    , либо

    $xml = New-Object Xml
    $xml.Load('C:\Test\file.xml')
    

    Последний - рекомендуемый подход, но в большинстве случаев первый будет работать так же хорошо.

  2. Значения в структурах данных XML являются строками, поэтому вам необходимо привести их к числовому типу, прежде чем вы сможете выполнить вычитание.

  3. Ваш код не присваивает измененное значение обратноузел XML.Без этого данные XML не будут обновляться, потому что операторы PowerShell возвращают результат вызывающей стороне.Они не обновляют первый операнд на месте.

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

    '{0:f4}' -f 1.3
    
  5. Использованиеточка доступа ($xml.NODE.NODE...) не позволяет присваивать измененное значение обратно узлу, поскольку этот подход уже расширяет значение конечного узла, поэтому $element содержит значение, а не узел.

Рекомендуемый способ сделать то, что вы хотите сделать, это использовать SelectNodes() с XPath выражением:

$xml = New-Object Xml
$xml.Load('C:\Test\file.xml')

$expr = '//UnitNetPrice'
$xml.SelectNodes($expr) | ForEach-Object {
    $_.'#text' = '{0:f4}' -f ([double]$_.'#text' - 1.0)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...