Как прочитать .xml в память и выписать тот же результат - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь прочитать XML-файл, изменить некоторые значения (пока нет) и выписать его обратно.Не внося никаких изменений, я ожидаю, что получится то же самое, что и вошло. Это не так.

PS H:\src\tws> type .\test000.xml
<?xml version="1.0"?>
<eventRuleSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules"
              xsi:schemaLocation="http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules/EventRules.xsd">
    <eventRule name="PW-TEST001" ruleType="filter" isDraft="no">
        <description>Paul's test001</description>
    </eventRule>
</eventRuleSet>

Вот простой код, который я использую, чтобы прочитать и записать его.

PS H:\src\tws> Get-Content .\con000.ps1
$x = [xml](Get-Content -Path .\test000.xml)
$x | Export-Clixml -Path .\con000.xml -Encoding utf8

Вывод имеет и разделы.Это почему?Я хотел бы получить то, что вошло. Меня не волнуют переводы строки или использование сущностей HTML.Я просто хочу, чтобы контент был сем.Да, план состоит в том, чтобы прочитать шаблон, изменить некоторые значения и вывести новый XML-файл.Это будет вход в планировщик рабочей нагрузки IBM / HCS.

PS H:\src\tws> type .\con000.xml
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <XD>&lt;?xml version="1.0"?&gt;&lt;eventRuleSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules" x
si:schemaLocation="http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules/EventRules.xsd"&gt;&lt;eventRule
name="PW-TEST001" ruleType="filter" isDraft="no"&gt;&lt;description&gt;Paul's test001&lt;/description&gt;&lt;/eventRule&gt;&lt;/eventRuleSet&gt;</XD>
</Objs>

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Поиграйте с этим кодом в отладчике.

$data1 = @"
<?xml version="1.0"?>
<eventRuleSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules"
              xsi:schemaLocation="http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules http://www.ibm.com/xmlns/prod/tws/1.0/event-management/rules/EventRules.xsd">
    <eventRule name="PW-TEST001" ruleType="filter" isDraft="no">
        <description>Paul's test001</description>
    </eventRule>
</eventRuleSet>
"@

$xml1 = [xml]$data1

"`n-------data1"
$data1

"`n--------xml1"
$xml1

"`n--------save to file xml2"
$xml1.Save('d:\test\xml2.xml')

$file2 = Get-Content 'd:\test\xml2.xml'
$xml2 = [xml]$file2

"`n--------file2"
$file2

"`n--------edit"
$xml2.eventRuleSet.eventRule.name = "Hello world!"

"`n--------save to file xml3"
$xml2.Save('d:\test\xml3.xml')

$file3 = Get-Content 'd:\test\xml3.xml'

"`n--------file3"
$file3
0 голосов
/ 26 октября 2018
  • Цель Export-CliXml состоит в сериализации произвольных объектов для последующего использования десериализации через Import-CliXml с использованием наилучшего представления с уважение к сохранению определенных типов ввода для последующей «регидратации» через Import-CliXml.

  • Его целью является , а не для записи текстового представления произвольных [xml] документов в файл.

Чтобы сохранить текстовое представление экземпляра [xml] в файл, у вас есть два основных варианта:

  • Если конкретное форматирование текстового представления документа XML не имеет значения , просто вызовите .OuterXml в (измененном) [xml] экземпляре и отправьте его в файл - либо через Set-Content, либо через Out-File / >, но обратите внимание на различные кодировки символов по умолчанию, применяемые этими командлетами в Windows PowerShell.

  • Используйте .NET framework , если хотите a Pretty-print Текстовое представление XML в выходном файле:

    • Метод .Save() типа [xml] удобно выполняет неявную симпатичную печать при сохранении в файл, но есть подводные камни:

      • Поскольку .NET обычно имеет другое представление о текущем каталоге, обязательно передайте полный путь к файлу .

      • При отсутствии объявления XML с атрибутом encoding метод создает файл UTF-8 без спецификации (что предпочтительно с кроссплатформенной точки зрения).

      • В отличие от этого, любопытно, что если XML-объявление с encoding="UTF-8" присутствует , результирующий файл будет UTF-8 с спецификацией, начиная с .NET Core 2.1 / .NET v4.7; см. этот выпуск GitHub .

    • Используйте экземпляр [System.Xml.XmlWriter] с явно созданным объектом файлового потока, который более громоздок, но дает вам контроль над особенностями печатного формата.


Вот простой пример с .OuterXml:

# Read the input file into an XML document (in-memory DOM).
$x = [xml] (Get-Content -Raw ./test000.xml)

# Make updates to the in-memory document
$x.eventRuleSet.eventRule.description = 'new description'

# Save the modified document as text to an output file,
# using the un-prettied textual representation provided by the .OuterXml
# property.
# If *BOM-less* UTF-8 encoding is what you want, simply use
#   $x.Save("$PWD/con000.xml")
# In PowerShell *Core*, you'd get BOM-less UTF-8 even with the command below.
$x.OuterXml | Set-Content -Encoding utf8 ./con000.xml

Примечание об использовании BOM (a.k.a. Unicode подпись) с UTF-8 и другими кодировками Unicode:

  • В Windows PowerShell , -Encoding utf8 неизменно создает спецификацию (применяется не только к Set-Content, но и к другим командлетам, которые производят вывод файла, например, Out-File и Export-Csv).

    • Для создания файлов BOM- less * UTF-8 требуется прямое использование .NET Framework (для функции оболочки, дружественной к PowerShell, см. мой ответ моего). Обратите внимание, что кодировка .NET Framework по умолчанию всегда была без спецификации UTF-8.
  • PowerShell Core создает BOM- меньше UTF-8 файлов по умолчанию (а также при явном использовании
    -Encoding utf8) ; Вы можете выбрать создание спецификации с помощью -Encoding utf8BOM.

Для лучшей общей совместимости следует избегать спецификаций в файлах UTF-8 избегать : платформы Unix и служебные программы Unix-наследия, также используемые на платформах Windows, обычно не знают, как с ними обращаться.

Точно так же следует избегать -Encoding UTF7, поскольку это не стандартная кодировка Unicode (и пишется без BOM в обеих редакциях PowerShell).

В в обеих версиях PowerShell все остальные кодировки Unicode, доступные с -Encoding do , создают (соответствующую кодировке) спецификацию: Unicode (UTF-16LE), bigendianunicode (UTF-16BE) и utf32 (UTF-32).

...