Как добавить данные журнала в XML-файлы? - PullRequest
0 голосов
/ 16 марта 2012

У меня есть лог-файл в общей папке.(Изначально он будет иметь только корневой элемент.).

Каждый раз, когда пользователи выполняют сценарий powershell, следующие данные журнала должны быть добавлены в XML.

<VM>
    <VMName>Fresh_R2VM</VMName>
    <AccessedBy>David</AccessedBy>
    <AccessedDate>Today's date</AccessedDate>
    <AccessedTime>current Time</AccessedTime>
</VM>

Мой файл журнала XML будет изначально похож наthis

<VirtualMachines version="1.0">

</virtualMachines>

Как только первый пользователь (Дэвид) выполнил сценарий, мой файл журнала должен быть таким.

<VirtualMachines version="1.0">
<VM>
    <VMName>Fresh_R2VM</VMName>
    <AccessedBy>David</AccessedBy>
    <AccessedDate>Today's date</AccessedDate>
    <AccessedTime>current Time</AccessedTime>
</VM>
</virtualMachines>

Если Дэвид выполняется второй раз, необходимо добавить еще одну запись.

<VirtualMachines version="1.0">
    <VM>
        <VMName>Fresh_R2VM</VMName>
        <AccessedBy>David</AccessedBy>
        <AccessedDate>Today's date</AccessedDate>
        <AccessedTime>current Time</AccessedTime>
    </VM>

    <VM>
        <VMName>Fresh_R2VM</VMName>
        <AccessedBy>David</AccessedBy>
        <AccessedDate>Today's date</AccessedDate>
        <AccessedTime>current Time</AccessedTime>
    </VM>
    </virtualMachines>

Я пытался добиться этого с помощью файла шаблона xml, а затем клонировать шаблон для регистрации файла и обновления.содержимое.Но он оставляет один пустой тег.Мне удалось удалить с помощью свойства removechild.

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

Как этого добиться?

1 Ответ

2 голосов
/ 16 марта 2012

Использование XML для файлов журналов - это плохой подход, поскольку это требует больших затрат, особенно если файл журнала становится большим;подробнее ниже.

Решение:

$file = Resolve-Path 'logfile.xml'
$output = [xml](Get-Content $file)
$vmNode = $output.DocumentElement

$newNode = [xml]@"
  <VM>
    <VMName>Fresh_R2VM</VMName>
    <AccessedBy>David</AccessedBy>
    <AccessedDate>$([DateTime]::Today)</AccessedDate>
    <AccessedTime>$([DateTime]::Now.ToString('HH:mm:ss'))</AccessedTime>
  </VM>
"@

# Need to move the VM node from document newNode to the output document
$newNode = $output.ImportNode($newNode.DocumentElement, $true)
$vmNode.appendChild($newNode) | out-null

$output.Save($file)

Производительность : каждый раз, когда это добавляет новый узел, он загружает и полностью анализирует существующий документ, чтобы затем добавить один узел,а затем сохраняет весь документ.Каждое добавление займет больше времени, чем предыдущее.С несколькими тысячами узлов это может быть значительным, с несколькими сотнями тысяч это, безусловно, будет.И анализируемый XML начинает становиться основным расходом памяти - XmlDocument объектам, представляющим нетривиальные документы XML, требуется много места.

Альтернативы

  1. Использовать текстовый файл.Только новые данные записываются непосредственно в конце (открыть файл, переместить позицию записи в конец и записать).Это не приводит к ухудшению размера файла, файлы с мегабайтами контента могут иметь больше данных, добавляемых так же быстро, как файл нового килобайта.Дополнительные инструменты для поиска файла (например, PowerShell Select-String может обрабатывать файл постепенно - опять же не нужно читать весь файл).

  2. Это что-то вроде хака: useDTD и сущность XML.LogFile.xml содержит DTD, определяющий внешнюю сущность, ссылающуюся на LogFileContent.xml-data.Затем узел <VirtualMachines> в LogFile.xml использует эту сущность для импорта LogFileContent.xml-data в качестве его дочерних элементов.Это означает, что LogFileContent.xml-data не обязательно должен быть действительным документом (не нужен его корневой элемент). Но это означает, что любые инструменты, обрабатывающие LogFile.xml, должны обрабатывать этот DTD (например, .NET, и, следовательно, PowerShell, поддержка XML отключает внешние сущности по умолчанию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...